ActivityManagerService.java revision f7097a5b697fedb6976774e55a51471405a23c0e
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_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
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
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * If set, the next time we collect PSS data we should do a full collection
574     * with data from native processes and the kernel.
575     */
576    boolean mFullPssPending = false;
577
578    /**
579     * This is the process holding what we currently consider to be
580     * the "home" activity.
581     */
582    ProcessRecord mHomeProcess;
583
584    /**
585     * This is the process holding the activity the user last visited that
586     * is in a different process from the one they are currently in.
587     */
588    ProcessRecord mPreviousProcess;
589
590    /**
591     * The time at which the previous process was last visible.
592     */
593    long mPreviousProcessVisibleTime;
594
595    /**
596     * Which uses have been started, so are allowed to run code.
597     */
598    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
599
600    /**
601     * LRU list of history of current users.  Most recently current is at the end.
602     */
603    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
604
605    /**
606     * Constant array of the users that are currently started.
607     */
608    int[] mStartedUserArray = new int[] { 0 };
609
610    /**
611     * Registered observers of the user switching mechanics.
612     */
613    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
614            = new RemoteCallbackList<IUserSwitchObserver>();
615
616    /**
617     * Currently active user switch.
618     */
619    Object mCurUserSwitchCallback;
620
621    /**
622     * Packages that the user has asked to have run in screen size
623     * compatibility mode instead of filling the screen.
624     */
625    final CompatModePackages mCompatModePackages;
626
627    /**
628     * Set of IntentSenderRecord objects that are currently active.
629     */
630    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
631            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
632
633    /**
634     * Fingerprints (hashCode()) of stack traces that we've
635     * already logged DropBox entries for.  Guarded by itself.  If
636     * something (rogue user app) forces this over
637     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
638     */
639    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
640    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
641
642    /**
643     * Strict Mode background batched logging state.
644     *
645     * The string buffer is guarded by itself, and its lock is also
646     * used to determine if another batched write is already
647     * in-flight.
648     */
649    private final StringBuilder mStrictModeBuffer = new StringBuilder();
650
651    /**
652     * Keeps track of all IIntentReceivers that have been registered for
653     * broadcasts.  Hash keys are the receiver IBinder, hash value is
654     * a ReceiverList.
655     */
656    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
657            new HashMap<IBinder, ReceiverList>();
658
659    /**
660     * Resolver for broadcast intents to registered receivers.
661     * Holds BroadcastFilter (subclass of IntentFilter).
662     */
663    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
664            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
665        @Override
666        protected boolean allowFilterResult(
667                BroadcastFilter filter, List<BroadcastFilter> dest) {
668            IBinder target = filter.receiverList.receiver.asBinder();
669            for (int i=dest.size()-1; i>=0; i--) {
670                if (dest.get(i).receiverList.receiver.asBinder() == target) {
671                    return false;
672                }
673            }
674            return true;
675        }
676
677        @Override
678        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
679            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
680                    || userId == filter.owningUserId) {
681                return super.newResult(filter, match, userId);
682            }
683            return null;
684        }
685
686        @Override
687        protected BroadcastFilter[] newArray(int size) {
688            return new BroadcastFilter[size];
689        }
690
691        @Override
692        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
693            return packageName.equals(filter.packageName);
694        }
695    };
696
697    /**
698     * State of all active sticky broadcasts per user.  Keys are the action of the
699     * sticky Intent, values are an ArrayList of all broadcasted intents with
700     * that action (which should usually be one).  The SparseArray is keyed
701     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
702     * for stickies that are sent to all users.
703     */
704    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
705            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
706
707    final ActiveServices mServices;
708
709    /**
710     * Backup/restore process management
711     */
712    String mBackupAppName = null;
713    BackupRecord mBackupTarget = null;
714
715    final ProviderMap mProviderMap;
716
717    /**
718     * List of content providers who have clients waiting for them.  The
719     * application is currently being launched and the provider will be
720     * removed from this list once it is published.
721     */
722    final ArrayList<ContentProviderRecord> mLaunchingProviders
723            = new ArrayList<ContentProviderRecord>();
724
725    /**
726     * File storing persisted {@link #mGrantedUriPermissions}.
727     */
728    private final AtomicFile mGrantFile;
729
730    /** XML constants used in {@link #mGrantFile} */
731    private static final String TAG_URI_GRANTS = "uri-grants";
732    private static final String TAG_URI_GRANT = "uri-grant";
733    private static final String ATTR_USER_HANDLE = "userHandle";
734    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
735    private static final String ATTR_TARGET_USER_ID = "targetUserId";
736    private static final String ATTR_SOURCE_PKG = "sourcePkg";
737    private static final String ATTR_TARGET_PKG = "targetPkg";
738    private static final String ATTR_URI = "uri";
739    private static final String ATTR_MODE_FLAGS = "modeFlags";
740    private static final String ATTR_CREATED_TIME = "createdTime";
741    private static final String ATTR_PREFIX = "prefix";
742
743    /**
744     * Global set of specific {@link Uri} permissions that have been granted.
745     * This optimized lookup structure maps from {@link UriPermission#targetUid}
746     * to {@link UriPermission#uri} to {@link UriPermission}.
747     */
748    @GuardedBy("this")
749    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
750            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
751
752    public static class GrantUri {
753        public final int sourceUserId;
754        public final Uri uri;
755        public boolean prefix;
756
757        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
758            this.sourceUserId = sourceUserId;
759            this.uri = uri;
760            this.prefix = prefix;
761        }
762
763        @Override
764        public int hashCode() {
765            return toString().hashCode();
766        }
767
768        @Override
769        public boolean equals(Object o) {
770            if (o instanceof GrantUri) {
771                GrantUri other = (GrantUri) o;
772                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
773                        && prefix == other.prefix;
774            }
775            return false;
776        }
777
778        @Override
779        public String toString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public String toSafeString() {
786            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
787            if (prefix) result += " [prefix]";
788            return result;
789        }
790
791        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
792            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
793                    ContentProvider.getUriWithoutUserId(uri), false);
794        }
795    }
796
797    CoreSettingsObserver mCoreSettingsObserver;
798
799    /**
800     * Thread-local storage used to carry caller permissions over through
801     * indirect content-provider access.
802     */
803    private class Identity {
804        public int pid;
805        public int uid;
806
807        Identity(int _pid, int _uid) {
808            pid = _pid;
809            uid = _uid;
810        }
811    }
812
813    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
814
815    /**
816     * All information we have collected about the runtime performance of
817     * any user id that can impact battery performance.
818     */
819    final BatteryStatsService mBatteryStatsService;
820
821    /**
822     * Information about component usage
823     */
824    final UsageStatsService mUsageStatsService;
825
826    /**
827     * Information about and control over application operations
828     */
829    final AppOpsService mAppOpsService;
830
831    /**
832     * Save recent tasks information across reboots.
833     */
834    final TaskPersister mTaskPersister;
835
836    /**
837     * Current configuration information.  HistoryRecord objects are given
838     * a reference to this object to indicate which configuration they are
839     * currently running in, so this object must be kept immutable.
840     */
841    Configuration mConfiguration = new Configuration();
842
843    /**
844     * Current sequencing integer of the configuration, for skipping old
845     * configurations.
846     */
847    int mConfigurationSeq = 0;
848
849    /**
850     * Hardware-reported OpenGLES version.
851     */
852    final int GL_ES_VERSION;
853
854    /**
855     * List of initialization arguments to pass to all processes when binding applications to them.
856     * For example, references to the commonly used services.
857     */
858    HashMap<String, IBinder> mAppBindArgs;
859
860    /**
861     * Temporary to avoid allocations.  Protected by main lock.
862     */
863    final StringBuilder mStringBuilder = new StringBuilder(256);
864
865    /**
866     * Used to control how we initialize the service.
867     */
868    ComponentName mTopComponent;
869    String mTopAction = Intent.ACTION_MAIN;
870    String mTopData;
871    boolean mProcessesReady = false;
872    boolean mSystemReady = false;
873    boolean mBooting = false;
874    boolean mWaitingUpdate = false;
875    boolean mDidUpdate = false;
876    boolean mOnBattery = false;
877    boolean mLaunchWarningShown = false;
878
879    Context mContext;
880
881    int mFactoryTest;
882
883    boolean mCheckedForSetup;
884
885    /**
886     * The time at which we will allow normal application switches again,
887     * after a call to {@link #stopAppSwitches()}.
888     */
889    long mAppSwitchesAllowedTime;
890
891    /**
892     * This is set to true after the first switch after mAppSwitchesAllowedTime
893     * is set; any switches after that will clear the time.
894     */
895    boolean mDidAppSwitch;
896
897    /**
898     * Last time (in realtime) at which we checked for power usage.
899     */
900    long mLastPowerCheckRealtime;
901
902    /**
903     * Last time (in uptime) at which we checked for power usage.
904     */
905    long mLastPowerCheckUptime;
906
907    /**
908     * Set while we are wanting to sleep, to prevent any
909     * activities from being started/resumed.
910     */
911    private boolean mSleeping = false;
912
913    /**
914     * Set while we are running a voice interaction.  This overrides
915     * sleeping while it is active.
916     */
917    private boolean mRunningVoice = false;
918
919    /**
920     * State of external calls telling us if the device is asleep.
921     */
922    private boolean mWentToSleep = false;
923
924    /**
925     * State of external call telling us if the lock screen is shown.
926     */
927    private boolean mLockScreenShown = false;
928
929    /**
930     * Set if we are shutting down the system, similar to sleeping.
931     */
932    boolean mShuttingDown = false;
933
934    /**
935     * Current sequence id for oom_adj computation traversal.
936     */
937    int mAdjSeq = 0;
938
939    /**
940     * Current sequence id for process LRU updating.
941     */
942    int mLruSeq = 0;
943
944    /**
945     * Keep track of the non-cached/empty process we last found, to help
946     * determine how to distribute cached/empty processes next time.
947     */
948    int mNumNonCachedProcs = 0;
949
950    /**
951     * Keep track of the number of cached hidden procs, to balance oom adj
952     * distribution between those and empty procs.
953     */
954    int mNumCachedHiddenProcs = 0;
955
956    /**
957     * Keep track of the number of service processes we last found, to
958     * determine on the next iteration which should be B services.
959     */
960    int mNumServiceProcs = 0;
961    int mNewNumAServiceProcs = 0;
962    int mNewNumServiceProcs = 0;
963
964    /**
965     * Allow the current computed overall memory level of the system to go down?
966     * This is set to false when we are killing processes for reasons other than
967     * memory management, so that the now smaller process list will not be taken as
968     * an indication that memory is tighter.
969     */
970    boolean mAllowLowerMemLevel = false;
971
972    /**
973     * The last computed memory level, for holding when we are in a state that
974     * processes are going away for other reasons.
975     */
976    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
977
978    /**
979     * The last total number of process we have, to determine if changes actually look
980     * like a shrinking number of process due to lower RAM.
981     */
982    int mLastNumProcesses;
983
984    /**
985     * The uptime of the last time we performed idle maintenance.
986     */
987    long mLastIdleTime = SystemClock.uptimeMillis();
988
989    /**
990     * Total time spent with RAM that has been added in the past since the last idle time.
991     */
992    long mLowRamTimeSinceLastIdle = 0;
993
994    /**
995     * If RAM is currently low, when that horrible situation started.
996     */
997    long mLowRamStartTime = 0;
998
999    /**
1000     * For reporting to battery stats the current top application.
1001     */
1002    private String mCurResumedPackage = null;
1003    private int mCurResumedUid = -1;
1004
1005    /**
1006     * For reporting to battery stats the apps currently running foreground
1007     * service.  The ProcessMap is package/uid tuples; each of these contain
1008     * an array of the currently foreground processes.
1009     */
1010    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1011            = new ProcessMap<ArrayList<ProcessRecord>>();
1012
1013    /**
1014     * This is set if we had to do a delayed dexopt of an app before launching
1015     * it, to increase the ANR timeouts in that case.
1016     */
1017    boolean mDidDexOpt;
1018
1019    /**
1020     * Set if the systemServer made a call to enterSafeMode.
1021     */
1022    boolean mSafeMode;
1023
1024    String mDebugApp = null;
1025    boolean mWaitForDebugger = false;
1026    boolean mDebugTransient = false;
1027    String mOrigDebugApp = null;
1028    boolean mOrigWaitForDebugger = false;
1029    boolean mAlwaysFinishActivities = false;
1030    IActivityController mController = null;
1031    String mProfileApp = null;
1032    ProcessRecord mProfileProc = null;
1033    String mProfileFile;
1034    ParcelFileDescriptor mProfileFd;
1035    int mProfileType = 0;
1036    boolean mAutoStopProfiler = false;
1037    String mOpenGlTraceApp = null;
1038
1039    static class ProcessChangeItem {
1040        static final int CHANGE_ACTIVITIES = 1<<0;
1041        static final int CHANGE_PROCESS_STATE = 1<<1;
1042        int changes;
1043        int uid;
1044        int pid;
1045        int processState;
1046        boolean foregroundActivities;
1047    }
1048
1049    final RemoteCallbackList<IProcessObserver> mProcessObservers
1050            = new RemoteCallbackList<IProcessObserver>();
1051    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1052
1053    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057
1058    /**
1059     * Runtime CPU use collection thread.  This object's lock is used to
1060     * protect all related state.
1061     */
1062    final Thread mProcessCpuThread;
1063
1064    /**
1065     * Used to collect process stats when showing not responding dialog.
1066     * Protected by mProcessCpuThread.
1067     */
1068    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1069            MONITOR_THREAD_CPU_USAGE);
1070    final AtomicLong mLastCpuTime = new AtomicLong(0);
1071    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1072
1073    long mLastWriteTime = 0;
1074
1075    /**
1076     * Used to retain an update lock when the foreground activity is in
1077     * immersive mode.
1078     */
1079    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1080
1081    /**
1082     * Set to true after the system has finished booting.
1083     */
1084    boolean mBooted = false;
1085
1086    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1087    int mProcessLimitOverride = -1;
1088
1089    WindowManagerService mWindowManager;
1090
1091    final ActivityThread mSystemThread;
1092
1093    int mCurrentUserId = 0;
1094    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1095    private UserManagerService mUserManager;
1096
1097    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1098        final ProcessRecord mApp;
1099        final int mPid;
1100        final IApplicationThread mAppThread;
1101
1102        AppDeathRecipient(ProcessRecord app, int pid,
1103                IApplicationThread thread) {
1104            if (localLOGV) Slog.v(
1105                TAG, "New death recipient " + this
1106                + " for thread " + thread.asBinder());
1107            mApp = app;
1108            mPid = pid;
1109            mAppThread = thread;
1110        }
1111
1112        @Override
1113        public void binderDied() {
1114            if (localLOGV) Slog.v(
1115                TAG, "Death received in " + this
1116                + " for thread " + mAppThread.asBinder());
1117            synchronized(ActivityManagerService.this) {
1118                appDiedLocked(mApp, mPid, mAppThread);
1119            }
1120        }
1121    }
1122
1123    static final int SHOW_ERROR_MSG = 1;
1124    static final int SHOW_NOT_RESPONDING_MSG = 2;
1125    static final int SHOW_FACTORY_ERROR_MSG = 3;
1126    static final int UPDATE_CONFIGURATION_MSG = 4;
1127    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1128    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1129    static final int SERVICE_TIMEOUT_MSG = 12;
1130    static final int UPDATE_TIME_ZONE = 13;
1131    static final int SHOW_UID_ERROR_MSG = 14;
1132    static final int IM_FEELING_LUCKY_MSG = 15;
1133    static final int PROC_START_TIMEOUT_MSG = 20;
1134    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1135    static final int KILL_APPLICATION_MSG = 22;
1136    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1137    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1138    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1139    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1140    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1141    static final int CLEAR_DNS_CACHE_MSG = 28;
1142    static final int UPDATE_HTTP_PROXY_MSG = 29;
1143    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1144    static final int DISPATCH_PROCESSES_CHANGED = 31;
1145    static final int DISPATCH_PROCESS_DIED = 32;
1146    static final int REPORT_MEM_USAGE_MSG = 33;
1147    static final int REPORT_USER_SWITCH_MSG = 34;
1148    static final int CONTINUE_USER_SWITCH_MSG = 35;
1149    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1150    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1151    static final int PERSIST_URI_GRANTS_MSG = 38;
1152    static final int REQUEST_ALL_PSS_MSG = 39;
1153    static final int START_PROFILES_MSG = 40;
1154    static final int UPDATE_TIME = 41;
1155    static final int SYSTEM_USER_START_MSG = 42;
1156    static final int SYSTEM_USER_CURRENT_MSG = 43;
1157
1158    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1159    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1160    static final int FIRST_COMPAT_MODE_MSG = 300;
1161    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1162
1163    AlertDialog mUidAlert;
1164    CompatModeDialog mCompatModeDialog;
1165    long mLastMemUsageReportTime = 0;
1166
1167    /**
1168     * Flag whether the current user is a "monkey", i.e. whether
1169     * the UI is driven by a UI automation tool.
1170     */
1171    private boolean mUserIsMonkey;
1172
1173    final ServiceThread mHandlerThread;
1174    final MainHandler mHandler;
1175
1176    final class MainHandler extends Handler {
1177        public MainHandler(Looper looper) {
1178            super(looper, null, true);
1179        }
1180
1181        @Override
1182        public void handleMessage(Message msg) {
1183            switch (msg.what) {
1184            case SHOW_ERROR_MSG: {
1185                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1186                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1187                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1188                synchronized (ActivityManagerService.this) {
1189                    ProcessRecord proc = (ProcessRecord)data.get("app");
1190                    AppErrorResult res = (AppErrorResult) data.get("result");
1191                    if (proc != null && proc.crashDialog != null) {
1192                        Slog.e(TAG, "App already has crash dialog: " + proc);
1193                        if (res != null) {
1194                            res.set(0);
1195                        }
1196                        return;
1197                    }
1198                    if (!showBackground && UserHandle.getAppId(proc.uid)
1199                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1200                            && proc.pid != MY_PID) {
1201                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                        return;
1206                    }
1207                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1208                        Dialog d = new AppErrorDialog(mContext,
1209                                ActivityManagerService.this, res, proc);
1210                        d.show();
1211                        proc.crashDialog = d;
1212                    } else {
1213                        // The device is asleep, so just pretend that the user
1214                        // saw a crash dialog and hit "force quit".
1215                        if (res != null) {
1216                            res.set(0);
1217                        }
1218                    }
1219                }
1220
1221                ensureBootCompleted();
1222            } break;
1223            case SHOW_NOT_RESPONDING_MSG: {
1224                synchronized (ActivityManagerService.this) {
1225                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1226                    ProcessRecord proc = (ProcessRecord)data.get("app");
1227                    if (proc != null && proc.anrDialog != null) {
1228                        Slog.e(TAG, "App already has anr dialog: " + proc);
1229                        return;
1230                    }
1231
1232                    Intent intent = new Intent("android.intent.action.ANR");
1233                    if (!mProcessesReady) {
1234                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1235                                | Intent.FLAG_RECEIVER_FOREGROUND);
1236                    }
1237                    broadcastIntentLocked(null, null, intent,
1238                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1239                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1240
1241                    if (mShowDialogs) {
1242                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1243                                mContext, proc, (ActivityRecord)data.get("activity"),
1244                                msg.arg1 != 0);
1245                        d.show();
1246                        proc.anrDialog = d;
1247                    } else {
1248                        // Just kill the app if there is no dialog to be shown.
1249                        killAppAtUsersRequest(proc, null);
1250                    }
1251                }
1252
1253                ensureBootCompleted();
1254            } break;
1255            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1256                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1257                synchronized (ActivityManagerService.this) {
1258                    ProcessRecord proc = (ProcessRecord) data.get("app");
1259                    if (proc == null) {
1260                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1261                        break;
1262                    }
1263                    if (proc.crashDialog != null) {
1264                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1265                        return;
1266                    }
1267                    AppErrorResult res = (AppErrorResult) data.get("result");
1268                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1269                        Dialog d = new StrictModeViolationDialog(mContext,
1270                                ActivityManagerService.this, res, proc);
1271                        d.show();
1272                        proc.crashDialog = d;
1273                    } else {
1274                        // The device is asleep, so just pretend that the user
1275                        // saw a crash dialog and hit "force quit".
1276                        res.set(0);
1277                    }
1278                }
1279                ensureBootCompleted();
1280            } break;
1281            case SHOW_FACTORY_ERROR_MSG: {
1282                Dialog d = new FactoryErrorDialog(
1283                    mContext, msg.getData().getCharSequence("msg"));
1284                d.show();
1285                ensureBootCompleted();
1286            } break;
1287            case UPDATE_CONFIGURATION_MSG: {
1288                final ContentResolver resolver = mContext.getContentResolver();
1289                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1290            } break;
1291            case GC_BACKGROUND_PROCESSES_MSG: {
1292                synchronized (ActivityManagerService.this) {
1293                    performAppGcsIfAppropriateLocked();
1294                }
1295            } break;
1296            case WAIT_FOR_DEBUGGER_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    ProcessRecord app = (ProcessRecord)msg.obj;
1299                    if (msg.arg1 != 0) {
1300                        if (!app.waitedForDebugger) {
1301                            Dialog d = new AppWaitingForDebuggerDialog(
1302                                    ActivityManagerService.this,
1303                                    mContext, app);
1304                            app.waitDialog = d;
1305                            app.waitedForDebugger = true;
1306                            d.show();
1307                        }
1308                    } else {
1309                        if (app.waitDialog != null) {
1310                            app.waitDialog.dismiss();
1311                            app.waitDialog = null;
1312                        }
1313                    }
1314                }
1315            } break;
1316            case SERVICE_TIMEOUT_MSG: {
1317                if (mDidDexOpt) {
1318                    mDidDexOpt = false;
1319                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1320                    nmsg.obj = msg.obj;
1321                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1322                    return;
1323                }
1324                mServices.serviceTimeout((ProcessRecord)msg.obj);
1325            } break;
1326            case UPDATE_TIME_ZONE: {
1327                synchronized (ActivityManagerService.this) {
1328                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1329                        ProcessRecord r = mLruProcesses.get(i);
1330                        if (r.thread != null) {
1331                            try {
1332                                r.thread.updateTimeZone();
1333                            } catch (RemoteException ex) {
1334                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1335                            }
1336                        }
1337                    }
1338                }
1339            } break;
1340            case CLEAR_DNS_CACHE_MSG: {
1341                synchronized (ActivityManagerService.this) {
1342                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1343                        ProcessRecord r = mLruProcesses.get(i);
1344                        if (r.thread != null) {
1345                            try {
1346                                r.thread.clearDnsCache();
1347                            } catch (RemoteException ex) {
1348                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1349                            }
1350                        }
1351                    }
1352                }
1353            } break;
1354            case UPDATE_HTTP_PROXY_MSG: {
1355                ProxyInfo proxy = (ProxyInfo)msg.obj;
1356                String host = "";
1357                String port = "";
1358                String exclList = "";
1359                Uri pacFileUrl = Uri.EMPTY;
1360                if (proxy != null) {
1361                    host = proxy.getHost();
1362                    port = Integer.toString(proxy.getPort());
1363                    exclList = proxy.getExclusionListAsString();
1364                    pacFileUrl = proxy.getPacFileUrl();
1365                }
1366                synchronized (ActivityManagerService.this) {
1367                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1368                        ProcessRecord r = mLruProcesses.get(i);
1369                        if (r.thread != null) {
1370                            try {
1371                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1372                            } catch (RemoteException ex) {
1373                                Slog.w(TAG, "Failed to update http proxy for: " +
1374                                        r.info.processName);
1375                            }
1376                        }
1377                    }
1378                }
1379            } break;
1380            case SHOW_UID_ERROR_MSG: {
1381                String title = "System UIDs Inconsistent";
1382                String text = "UIDs on the system are inconsistent, you need to wipe your"
1383                        + " data partition or your device will be unstable.";
1384                Log.e(TAG, title + ": " + text);
1385                if (mShowDialogs) {
1386                    // XXX This is a temporary dialog, no need to localize.
1387                    AlertDialog d = new BaseErrorDialog(mContext);
1388                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1389                    d.setCancelable(false);
1390                    d.setTitle(title);
1391                    d.setMessage(text);
1392                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1393                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1394                    mUidAlert = d;
1395                    d.show();
1396                }
1397            } break;
1398            case IM_FEELING_LUCKY_MSG: {
1399                if (mUidAlert != null) {
1400                    mUidAlert.dismiss();
1401                    mUidAlert = null;
1402                }
1403            } break;
1404            case PROC_START_TIMEOUT_MSG: {
1405                if (mDidDexOpt) {
1406                    mDidDexOpt = false;
1407                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1408                    nmsg.obj = msg.obj;
1409                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1410                    return;
1411                }
1412                ProcessRecord app = (ProcessRecord)msg.obj;
1413                synchronized (ActivityManagerService.this) {
1414                    processStartTimedOutLocked(app);
1415                }
1416            } break;
1417            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    doPendingActivityLaunchesLocked(true);
1420                }
1421            } break;
1422            case KILL_APPLICATION_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    int appid = msg.arg1;
1425                    boolean restart = (msg.arg2 == 1);
1426                    Bundle bundle = (Bundle)msg.obj;
1427                    String pkg = bundle.getString("pkg");
1428                    String reason = bundle.getString("reason");
1429                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1430                            false, UserHandle.USER_ALL, reason);
1431                }
1432            } break;
1433            case FINALIZE_PENDING_INTENT_MSG: {
1434                ((PendingIntentRecord)msg.obj).completeFinalize();
1435            } break;
1436            case POST_HEAVY_NOTIFICATION_MSG: {
1437                INotificationManager inm = NotificationManager.getService();
1438                if (inm == null) {
1439                    return;
1440                }
1441
1442                ActivityRecord root = (ActivityRecord)msg.obj;
1443                ProcessRecord process = root.app;
1444                if (process == null) {
1445                    return;
1446                }
1447
1448                try {
1449                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1450                    String text = mContext.getString(R.string.heavy_weight_notification,
1451                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1452                    Notification notification = new Notification();
1453                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1454                    notification.when = 0;
1455                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1456                    notification.tickerText = text;
1457                    notification.defaults = 0; // please be quiet
1458                    notification.sound = null;
1459                    notification.vibrate = null;
1460                    notification.setLatestEventInfo(context, text,
1461                            mContext.getText(R.string.heavy_weight_notification_detail),
1462                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1463                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1464                                    new UserHandle(root.userId)));
1465
1466                    try {
1467                        int[] outId = new int[1];
1468                        inm.enqueueNotificationWithTag("android", "android", null,
1469                                R.string.heavy_weight_notification,
1470                                notification, outId, root.userId);
1471                    } catch (RuntimeException e) {
1472                        Slog.w(ActivityManagerService.TAG,
1473                                "Error showing notification for heavy-weight app", e);
1474                    } catch (RemoteException e) {
1475                    }
1476                } catch (NameNotFoundException e) {
1477                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1478                }
1479            } break;
1480            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1481                INotificationManager inm = NotificationManager.getService();
1482                if (inm == null) {
1483                    return;
1484                }
1485                try {
1486                    inm.cancelNotificationWithTag("android", null,
1487                            R.string.heavy_weight_notification,  msg.arg1);
1488                } catch (RuntimeException e) {
1489                    Slog.w(ActivityManagerService.TAG,
1490                            "Error canceling notification for service", e);
1491                } catch (RemoteException e) {
1492                }
1493            } break;
1494            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1495                synchronized (ActivityManagerService.this) {
1496                    checkExcessivePowerUsageLocked(true);
1497                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1498                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1499                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1500                }
1501            } break;
1502            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1503                synchronized (ActivityManagerService.this) {
1504                    ActivityRecord ar = (ActivityRecord)msg.obj;
1505                    if (mCompatModeDialog != null) {
1506                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1507                                ar.info.applicationInfo.packageName)) {
1508                            return;
1509                        }
1510                        mCompatModeDialog.dismiss();
1511                        mCompatModeDialog = null;
1512                    }
1513                    if (ar != null && false) {
1514                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1515                                ar.packageName)) {
1516                            int mode = mCompatModePackages.computeCompatModeLocked(
1517                                    ar.info.applicationInfo);
1518                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1519                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1520                                mCompatModeDialog = new CompatModeDialog(
1521                                        ActivityManagerService.this, mContext,
1522                                        ar.info.applicationInfo);
1523                                mCompatModeDialog.show();
1524                            }
1525                        }
1526                    }
1527                }
1528                break;
1529            }
1530            case DISPATCH_PROCESSES_CHANGED: {
1531                dispatchProcessesChanged();
1532                break;
1533            }
1534            case DISPATCH_PROCESS_DIED: {
1535                final int pid = msg.arg1;
1536                final int uid = msg.arg2;
1537                dispatchProcessDied(pid, uid);
1538                break;
1539            }
1540            case REPORT_MEM_USAGE_MSG: {
1541                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1542                Thread thread = new Thread() {
1543                    @Override public void run() {
1544                        final SparseArray<ProcessMemInfo> infoMap
1545                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1546                        for (int i=0, N=memInfos.size(); i<N; i++) {
1547                            ProcessMemInfo mi = memInfos.get(i);
1548                            infoMap.put(mi.pid, mi);
1549                        }
1550                        updateCpuStatsNow();
1551                        synchronized (mProcessCpuThread) {
1552                            final int N = mProcessCpuTracker.countStats();
1553                            for (int i=0; i<N; i++) {
1554                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1555                                if (st.vsize > 0) {
1556                                    long pss = Debug.getPss(st.pid, null);
1557                                    if (pss > 0) {
1558                                        if (infoMap.indexOfKey(st.pid) < 0) {
1559                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1560                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1561                                            mi.pss = pss;
1562                                            memInfos.add(mi);
1563                                        }
1564                                    }
1565                                }
1566                            }
1567                        }
1568
1569                        long totalPss = 0;
1570                        for (int i=0, N=memInfos.size(); i<N; i++) {
1571                            ProcessMemInfo mi = memInfos.get(i);
1572                            if (mi.pss == 0) {
1573                                mi.pss = Debug.getPss(mi.pid, null);
1574                            }
1575                            totalPss += mi.pss;
1576                        }
1577                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1578                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1579                                if (lhs.oomAdj != rhs.oomAdj) {
1580                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1581                                }
1582                                if (lhs.pss != rhs.pss) {
1583                                    return lhs.pss < rhs.pss ? 1 : -1;
1584                                }
1585                                return 0;
1586                            }
1587                        });
1588
1589                        StringBuilder tag = new StringBuilder(128);
1590                        StringBuilder stack = new StringBuilder(128);
1591                        tag.append("Low on memory -- ");
1592                        appendMemBucket(tag, totalPss, "total", false);
1593                        appendMemBucket(stack, totalPss, "total", true);
1594
1595                        StringBuilder logBuilder = new StringBuilder(1024);
1596                        logBuilder.append("Low on memory:\n");
1597
1598                        boolean firstLine = true;
1599                        int lastOomAdj = Integer.MIN_VALUE;
1600                        for (int i=0, N=memInfos.size(); i<N; i++) {
1601                            ProcessMemInfo mi = memInfos.get(i);
1602
1603                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1604                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1605                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1606                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1607                                if (lastOomAdj != mi.oomAdj) {
1608                                    lastOomAdj = mi.oomAdj;
1609                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1610                                        tag.append(" / ");
1611                                    }
1612                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1613                                        if (firstLine) {
1614                                            stack.append(":");
1615                                            firstLine = false;
1616                                        }
1617                                        stack.append("\n\t at ");
1618                                    } else {
1619                                        stack.append("$");
1620                                    }
1621                                } else {
1622                                    tag.append(" ");
1623                                    stack.append("$");
1624                                }
1625                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1626                                    appendMemBucket(tag, mi.pss, mi.name, false);
1627                                }
1628                                appendMemBucket(stack, mi.pss, mi.name, true);
1629                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1630                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1631                                    stack.append("(");
1632                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1633                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1634                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1635                                            stack.append(":");
1636                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1637                                        }
1638                                    }
1639                                    stack.append(")");
1640                                }
1641                            }
1642
1643                            logBuilder.append("  ");
1644                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1645                            logBuilder.append(' ');
1646                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1647                            logBuilder.append(' ');
1648                            ProcessList.appendRamKb(logBuilder, mi.pss);
1649                            logBuilder.append(" kB: ");
1650                            logBuilder.append(mi.name);
1651                            logBuilder.append(" (");
1652                            logBuilder.append(mi.pid);
1653                            logBuilder.append(") ");
1654                            logBuilder.append(mi.adjType);
1655                            logBuilder.append('\n');
1656                            if (mi.adjReason != null) {
1657                                logBuilder.append("                      ");
1658                                logBuilder.append(mi.adjReason);
1659                                logBuilder.append('\n');
1660                            }
1661                        }
1662
1663                        logBuilder.append("           ");
1664                        ProcessList.appendRamKb(logBuilder, totalPss);
1665                        logBuilder.append(" kB: TOTAL\n");
1666
1667                        long[] infos = new long[Debug.MEMINFO_COUNT];
1668                        Debug.getMemInfo(infos);
1669                        logBuilder.append("  MemInfo: ");
1670                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1671                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1672                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1673                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1674                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1675                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1676                            logBuilder.append("  ZRAM: ");
1677                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1678                            logBuilder.append(" kB RAM, ");
1679                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1680                            logBuilder.append(" kB swap total, ");
1681                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1682                            logBuilder.append(" kB swap free\n");
1683                        }
1684                        Slog.i(TAG, logBuilder.toString());
1685
1686                        StringBuilder dropBuilder = new StringBuilder(1024);
1687                        /*
1688                        StringWriter oomSw = new StringWriter();
1689                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1690                        StringWriter catSw = new StringWriter();
1691                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1692                        String[] emptyArgs = new String[] { };
1693                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1694                        oomPw.flush();
1695                        String oomString = oomSw.toString();
1696                        */
1697                        dropBuilder.append(stack);
1698                        dropBuilder.append('\n');
1699                        dropBuilder.append('\n');
1700                        dropBuilder.append(logBuilder);
1701                        dropBuilder.append('\n');
1702                        /*
1703                        dropBuilder.append(oomString);
1704                        dropBuilder.append('\n');
1705                        */
1706                        StringWriter catSw = new StringWriter();
1707                        synchronized (ActivityManagerService.this) {
1708                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1709                            String[] emptyArgs = new String[] { };
1710                            catPw.println();
1711                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1712                            catPw.println();
1713                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1714                                    false, false, null);
1715                            catPw.println();
1716                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1717                            catPw.flush();
1718                        }
1719                        dropBuilder.append(catSw.toString());
1720                        addErrorToDropBox("lowmem", null, "system_server", null,
1721                                null, tag.toString(), dropBuilder.toString(), null, null);
1722                        //Slog.i(TAG, "Sent to dropbox:");
1723                        //Slog.i(TAG, dropBuilder.toString());
1724                        synchronized (ActivityManagerService.this) {
1725                            long now = SystemClock.uptimeMillis();
1726                            if (mLastMemUsageReportTime < now) {
1727                                mLastMemUsageReportTime = now;
1728                            }
1729                        }
1730                    }
1731                };
1732                thread.start();
1733                break;
1734            }
1735            case REPORT_USER_SWITCH_MSG: {
1736                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1737                break;
1738            }
1739            case CONTINUE_USER_SWITCH_MSG: {
1740                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1741                break;
1742            }
1743            case USER_SWITCH_TIMEOUT_MSG: {
1744                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1745                break;
1746            }
1747            case IMMERSIVE_MODE_LOCK_MSG: {
1748                final boolean nextState = (msg.arg1 != 0);
1749                if (mUpdateLock.isHeld() != nextState) {
1750                    if (DEBUG_IMMERSIVE) {
1751                        final ActivityRecord r = (ActivityRecord) msg.obj;
1752                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1753                    }
1754                    if (nextState) {
1755                        mUpdateLock.acquire();
1756                    } else {
1757                        mUpdateLock.release();
1758                    }
1759                }
1760                break;
1761            }
1762            case PERSIST_URI_GRANTS_MSG: {
1763                writeGrantedUriPermissions();
1764                break;
1765            }
1766            case REQUEST_ALL_PSS_MSG: {
1767                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1768                break;
1769            }
1770            case START_PROFILES_MSG: {
1771                synchronized (ActivityManagerService.this) {
1772                    startProfilesLocked();
1773                }
1774                break;
1775            }
1776            case UPDATE_TIME: {
1777                synchronized (ActivityManagerService.this) {
1778                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1779                        ProcessRecord r = mLruProcesses.get(i);
1780                        if (r.thread != null) {
1781                            try {
1782                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1783                            } catch (RemoteException ex) {
1784                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1785                            }
1786                        }
1787                    }
1788                }
1789                break;
1790            }
1791            case SYSTEM_USER_START_MSG: {
1792                mSystemServiceManager.startUser(msg.arg1);
1793                break;
1794            }
1795            case SYSTEM_USER_CURRENT_MSG: {
1796                mSystemServiceManager.switchUser(msg.arg1);
1797                break;
1798            }
1799            }
1800        }
1801    };
1802
1803    static final int COLLECT_PSS_BG_MSG = 1;
1804
1805    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1806        @Override
1807        public void handleMessage(Message msg) {
1808            switch (msg.what) {
1809            case COLLECT_PSS_BG_MSG: {
1810                long start = SystemClock.uptimeMillis();
1811                MemInfoReader memInfo = null;
1812                synchronized (ActivityManagerService.this) {
1813                    if (mFullPssPending) {
1814                        mFullPssPending = false;
1815                        memInfo = new MemInfoReader();
1816                    }
1817                }
1818                if (memInfo != null) {
1819                    updateCpuStatsNow();
1820                    long nativeTotalPss = 0;
1821                    synchronized (mProcessCpuThread) {
1822                        final int N = mProcessCpuTracker.countStats();
1823                        for (int j=0; j<N; j++) {
1824                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1825                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID
1826                                    || st.uid == Process.SYSTEM_UID) {
1827                                // This is definitely an application process; skip it.
1828                                continue;
1829                            }
1830                            synchronized (mPidsSelfLocked) {
1831                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1832                                    // This is one of our own processes; skip it.
1833                                    continue;
1834                                }
1835                            }
1836                            nativeTotalPss += Debug.getPss(st.pid, null);
1837                        }
1838                    }
1839                    memInfo.readMemInfo();
1840                    synchronized (this) {
1841                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1842                                + (SystemClock.uptimeMillis()-start) + "ms");
1843                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1844                                memInfo.getFreeSizeKb(),
1845                                memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
1846                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1847                                        +memInfo.getSlabSizeKb(),
1848                                nativeTotalPss);
1849                    }
1850                }
1851
1852                int i=0, num=0;
1853                long[] tmp = new long[1];
1854                do {
1855                    ProcessRecord proc;
1856                    int procState;
1857                    int pid;
1858                    synchronized (ActivityManagerService.this) {
1859                        if (i >= mPendingPssProcesses.size()) {
1860                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1861                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1862                            mPendingPssProcesses.clear();
1863                            return;
1864                        }
1865                        proc = mPendingPssProcesses.get(i);
1866                        procState = proc.pssProcState;
1867                        if (proc.thread != null && procState == proc.setProcState) {
1868                            pid = proc.pid;
1869                        } else {
1870                            proc = null;
1871                            pid = 0;
1872                        }
1873                        i++;
1874                    }
1875                    if (proc != null) {
1876                        long pss = Debug.getPss(pid, tmp);
1877                        synchronized (ActivityManagerService.this) {
1878                            if (proc.thread != null && proc.setProcState == procState
1879                                    && proc.pid == pid) {
1880                                num++;
1881                                proc.lastPssTime = SystemClock.uptimeMillis();
1882                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1883                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1884                                        + ": " + pss + " lastPss=" + proc.lastPss
1885                                        + " state=" + ProcessList.makeProcStateString(procState));
1886                                if (proc.initialIdlePss == 0) {
1887                                    proc.initialIdlePss = pss;
1888                                }
1889                                proc.lastPss = pss;
1890                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1891                                    proc.lastCachedPss = pss;
1892                                }
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    /**
1903     * Monitor for package changes and update our internal state.
1904     */
1905    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1906        @Override
1907        public void onPackageRemoved(String packageName, int uid) {
1908            // Remove all tasks with activities in the specified package from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1911                    TaskRecord tr = mRecentTasks.get(i);
1912                    ComponentName cn = tr.intent.getComponent();
1913                    if (cn != null && cn.getPackageName().equals(packageName)) {
1914                        // If the package name matches, remove the task and kill the process
1915                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1916                    }
1917                }
1918            }
1919        }
1920
1921        @Override
1922        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1923            onPackageModified(packageName);
1924            return true;
1925        }
1926
1927        @Override
1928        public void onPackageModified(String packageName) {
1929            final PackageManager pm = mContext.getPackageManager();
1930            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1931                    new ArrayList<Pair<Intent, Integer>>();
1932            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1933            // Copy the list of recent tasks so that we don't hold onto the lock on
1934            // ActivityManagerService for long periods while checking if components exist.
1935            synchronized (ActivityManagerService.this) {
1936                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1937                    TaskRecord tr = mRecentTasks.get(i);
1938                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1939                }
1940            }
1941            // Check the recent tasks and filter out all tasks with components that no longer exist.
1942            Intent tmpI = new Intent();
1943            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1944                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1945                ComponentName cn = p.first.getComponent();
1946                if (cn != null && cn.getPackageName().equals(packageName)) {
1947                    try {
1948                        // Add the task to the list to remove if the component no longer exists
1949                        tmpI.setComponent(cn);
1950                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1951                            tasksToRemove.add(p.second);
1952                        }
1953                    } catch (Exception e) {}
1954                }
1955            }
1956            // Prune all the tasks with removed components from the list of recent tasks
1957            synchronized (ActivityManagerService.this) {
1958                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1959                    // Remove the task but don't kill the process (since other components in that
1960                    // package may still be running and in the background)
1961                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1962                }
1963            }
1964        }
1965
1966        @Override
1967        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1968            // Force stop the specified packages
1969            if (packages != null) {
1970                for (String pkg : packages) {
1971                    synchronized (ActivityManagerService.this) {
1972                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1973                                "finished booting")) {
1974                            return true;
1975                        }
1976                    }
1977                }
1978            }
1979            return false;
1980        }
1981    };
1982
1983    public void setSystemProcess() {
1984        try {
1985            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1986            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1987            ServiceManager.addService("meminfo", new MemBinder(this));
1988            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1989            ServiceManager.addService("dbinfo", new DbBinder(this));
1990            if (MONITOR_CPU_USAGE) {
1991                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1992            }
1993            ServiceManager.addService("permission", new PermissionController(this));
1994
1995            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1996                    "android", STOCK_PM_FLAGS);
1997            mSystemThread.installSystemApplicationInfo(info);
1998
1999            synchronized (this) {
2000                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2001                app.persistent = true;
2002                app.pid = MY_PID;
2003                app.maxAdj = ProcessList.SYSTEM_ADJ;
2004                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2005                mProcessNames.put(app.processName, app.uid, app);
2006                synchronized (mPidsSelfLocked) {
2007                    mPidsSelfLocked.put(app.pid, app);
2008                }
2009                updateLruProcessLocked(app, false, null);
2010                updateOomAdjLocked();
2011            }
2012        } catch (PackageManager.NameNotFoundException e) {
2013            throw new RuntimeException(
2014                    "Unable to find android system package", e);
2015        }
2016    }
2017
2018    public void setWindowManager(WindowManagerService wm) {
2019        mWindowManager = wm;
2020        mStackSupervisor.setWindowManager(wm);
2021    }
2022
2023    public void startObservingNativeCrashes() {
2024        final NativeCrashListener ncl = new NativeCrashListener(this);
2025        ncl.start();
2026    }
2027
2028    public IAppOpsService getAppOpsService() {
2029        return mAppOpsService;
2030    }
2031
2032    static class MemBinder extends Binder {
2033        ActivityManagerService mActivityManagerService;
2034        MemBinder(ActivityManagerService activityManagerService) {
2035            mActivityManagerService = activityManagerService;
2036        }
2037
2038        @Override
2039        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2040            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2041                    != PackageManager.PERMISSION_GRANTED) {
2042                pw.println("Permission Denial: can't dump meminfo from from pid="
2043                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2044                        + " without permission " + android.Manifest.permission.DUMP);
2045                return;
2046            }
2047
2048            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2049        }
2050    }
2051
2052    static class GraphicsBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        GraphicsBinder(ActivityManagerService activityManagerService) {
2055            mActivityManagerService = activityManagerService;
2056        }
2057
2058        @Override
2059        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2060            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2061                    != PackageManager.PERMISSION_GRANTED) {
2062                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2069        }
2070    }
2071
2072    static class DbBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        DbBinder(ActivityManagerService activityManagerService) {
2075            mActivityManagerService = activityManagerService;
2076        }
2077
2078        @Override
2079        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2081                    != PackageManager.PERMISSION_GRANTED) {
2082                pw.println("Permission Denial: can't dump dbinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpDbInfo(fd, pw, args);
2089        }
2090    }
2091
2092    static class CpuBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        CpuBinder(ActivityManagerService activityManagerService) {
2095            mActivityManagerService = activityManagerService;
2096        }
2097
2098        @Override
2099        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2100            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2101                    != PackageManager.PERMISSION_GRANTED) {
2102                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            synchronized (mActivityManagerService.mProcessCpuThread) {
2109                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2110                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2111                        SystemClock.uptimeMillis()));
2112            }
2113        }
2114    }
2115
2116    public static final class Lifecycle extends SystemService {
2117        private final ActivityManagerService mService;
2118
2119        public Lifecycle(Context context) {
2120            super(context);
2121            mService = new ActivityManagerService(context);
2122        }
2123
2124        @Override
2125        public void onStart() {
2126            mService.start();
2127        }
2128
2129        public ActivityManagerService getService() {
2130            return mService;
2131        }
2132    }
2133
2134    // Note: This method is invoked on the main thread but may need to attach various
2135    // handlers to other threads.  So take care to be explicit about the looper.
2136    public ActivityManagerService(Context systemContext) {
2137        mContext = systemContext;
2138        mFactoryTest = FactoryTest.getMode();
2139        mSystemThread = ActivityThread.currentActivityThread();
2140
2141        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2142
2143        mHandlerThread = new ServiceThread(TAG,
2144                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2145        mHandlerThread.start();
2146        mHandler = new MainHandler(mHandlerThread.getLooper());
2147
2148        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2149                "foreground", BROADCAST_FG_TIMEOUT, false);
2150        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2151                "background", BROADCAST_BG_TIMEOUT, true);
2152        mBroadcastQueues[0] = mFgBroadcastQueue;
2153        mBroadcastQueues[1] = mBgBroadcastQueue;
2154
2155        mServices = new ActiveServices(this);
2156        mProviderMap = new ProviderMap(this);
2157
2158        // TODO: Move creation of battery stats service outside of activity manager service.
2159        File dataDir = Environment.getDataDirectory();
2160        File systemDir = new File(dataDir, "system");
2161        systemDir.mkdirs();
2162        mBatteryStatsService = new BatteryStatsService(new File(
2163                systemDir, "batterystats.bin").toString(), mHandler);
2164        mBatteryStatsService.getActiveStatistics().readLocked();
2165        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2166        mOnBattery = DEBUG_POWER ? true
2167                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2168        mBatteryStatsService.getActiveStatistics().setCallback(this);
2169
2170        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2171
2172        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2173        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2174
2175        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2176
2177        // User 0 is the first and only user that runs at boot.
2178        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2179        mUserLru.add(Integer.valueOf(0));
2180        updateStartedUserArrayLocked();
2181
2182        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2183            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2184
2185        mConfiguration.setToDefaults();
2186        mConfiguration.setLocale(Locale.getDefault());
2187
2188        mConfigurationSeq = mConfiguration.seq = 1;
2189        mProcessCpuTracker.init();
2190
2191        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2192        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2193        mStackSupervisor = new ActivityStackSupervisor(this);
2194        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2195
2196        mProcessCpuThread = new Thread("CpuTracker") {
2197            @Override
2198            public void run() {
2199                while (true) {
2200                    try {
2201                        try {
2202                            synchronized(this) {
2203                                final long now = SystemClock.uptimeMillis();
2204                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2205                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2206                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2207                                //        + ", write delay=" + nextWriteDelay);
2208                                if (nextWriteDelay < nextCpuDelay) {
2209                                    nextCpuDelay = nextWriteDelay;
2210                                }
2211                                if (nextCpuDelay > 0) {
2212                                    mProcessCpuMutexFree.set(true);
2213                                    this.wait(nextCpuDelay);
2214                                }
2215                            }
2216                        } catch (InterruptedException e) {
2217                        }
2218                        updateCpuStatsNow();
2219                    } catch (Exception e) {
2220                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2221                    }
2222                }
2223            }
2224        };
2225
2226        Watchdog.getInstance().addMonitor(this);
2227        Watchdog.getInstance().addThread(mHandler);
2228    }
2229
2230    public void setSystemServiceManager(SystemServiceManager mgr) {
2231        mSystemServiceManager = mgr;
2232    }
2233
2234    private void start() {
2235        mProcessCpuThread.start();
2236
2237        mBatteryStatsService.publish(mContext);
2238        mUsageStatsService.publish(mContext);
2239        mAppOpsService.publish(mContext);
2240        Slog.d("AppOps", "AppOpsService published");
2241        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2242    }
2243
2244    @Override
2245    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2246            throws RemoteException {
2247        if (code == SYSPROPS_TRANSACTION) {
2248            // We need to tell all apps about the system property change.
2249            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2250            synchronized(this) {
2251                final int NP = mProcessNames.getMap().size();
2252                for (int ip=0; ip<NP; ip++) {
2253                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2254                    final int NA = apps.size();
2255                    for (int ia=0; ia<NA; ia++) {
2256                        ProcessRecord app = apps.valueAt(ia);
2257                        if (app.thread != null) {
2258                            procs.add(app.thread.asBinder());
2259                        }
2260                    }
2261                }
2262            }
2263
2264            int N = procs.size();
2265            for (int i=0; i<N; i++) {
2266                Parcel data2 = Parcel.obtain();
2267                try {
2268                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2269                } catch (RemoteException e) {
2270                }
2271                data2.recycle();
2272            }
2273        }
2274        try {
2275            return super.onTransact(code, data, reply, flags);
2276        } catch (RuntimeException e) {
2277            // The activity manager only throws security exceptions, so let's
2278            // log all others.
2279            if (!(e instanceof SecurityException)) {
2280                Slog.wtf(TAG, "Activity Manager Crash", e);
2281            }
2282            throw e;
2283        }
2284    }
2285
2286    void updateCpuStats() {
2287        final long now = SystemClock.uptimeMillis();
2288        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2289            return;
2290        }
2291        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2292            synchronized (mProcessCpuThread) {
2293                mProcessCpuThread.notify();
2294            }
2295        }
2296    }
2297
2298    void updateCpuStatsNow() {
2299        synchronized (mProcessCpuThread) {
2300            mProcessCpuMutexFree.set(false);
2301            final long now = SystemClock.uptimeMillis();
2302            boolean haveNewCpuStats = false;
2303
2304            if (MONITOR_CPU_USAGE &&
2305                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2306                mLastCpuTime.set(now);
2307                haveNewCpuStats = true;
2308                mProcessCpuTracker.update();
2309                //Slog.i(TAG, mProcessCpu.printCurrentState());
2310                //Slog.i(TAG, "Total CPU usage: "
2311                //        + mProcessCpu.getTotalCpuPercent() + "%");
2312
2313                // Slog the cpu usage if the property is set.
2314                if ("true".equals(SystemProperties.get("events.cpu"))) {
2315                    int user = mProcessCpuTracker.getLastUserTime();
2316                    int system = mProcessCpuTracker.getLastSystemTime();
2317                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2318                    int irq = mProcessCpuTracker.getLastIrqTime();
2319                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2320                    int idle = mProcessCpuTracker.getLastIdleTime();
2321
2322                    int total = user + system + iowait + irq + softIrq + idle;
2323                    if (total == 0) total = 1;
2324
2325                    EventLog.writeEvent(EventLogTags.CPU,
2326                            ((user+system+iowait+irq+softIrq) * 100) / total,
2327                            (user * 100) / total,
2328                            (system * 100) / total,
2329                            (iowait * 100) / total,
2330                            (irq * 100) / total,
2331                            (softIrq * 100) / total);
2332                }
2333            }
2334
2335            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2336            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2337            synchronized(bstats) {
2338                synchronized(mPidsSelfLocked) {
2339                    if (haveNewCpuStats) {
2340                        if (mOnBattery) {
2341                            int perc = bstats.startAddingCpuLocked();
2342                            int totalUTime = 0;
2343                            int totalSTime = 0;
2344                            final int N = mProcessCpuTracker.countStats();
2345                            for (int i=0; i<N; i++) {
2346                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2347                                if (!st.working) {
2348                                    continue;
2349                                }
2350                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2351                                int otherUTime = (st.rel_utime*perc)/100;
2352                                int otherSTime = (st.rel_stime*perc)/100;
2353                                totalUTime += otherUTime;
2354                                totalSTime += otherSTime;
2355                                if (pr != null) {
2356                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2357                                    if (ps == null || !ps.isActive()) {
2358                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2359                                                pr.info.uid, pr.processName);
2360                                    }
2361                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2362                                            st.rel_stime-otherSTime);
2363                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2364                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2365                                } else {
2366                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2367                                    if (ps == null || !ps.isActive()) {
2368                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2369                                                bstats.mapUid(st.uid), st.name);
2370                                    }
2371                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2372                                            st.rel_stime-otherSTime);
2373                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2374                                }
2375                            }
2376                            bstats.finishAddingCpuLocked(perc, totalUTime,
2377                                    totalSTime, cpuSpeedTimes);
2378                        }
2379                    }
2380                }
2381
2382                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2383                    mLastWriteTime = now;
2384                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2385                }
2386            }
2387        }
2388    }
2389
2390    @Override
2391    public void batteryNeedsCpuUpdate() {
2392        updateCpuStatsNow();
2393    }
2394
2395    @Override
2396    public void batteryPowerChanged(boolean onBattery) {
2397        // When plugging in, update the CPU stats first before changing
2398        // the plug state.
2399        updateCpuStatsNow();
2400        synchronized (this) {
2401            synchronized(mPidsSelfLocked) {
2402                mOnBattery = DEBUG_POWER ? true : onBattery;
2403            }
2404        }
2405    }
2406
2407    /**
2408     * Initialize the application bind args. These are passed to each
2409     * process when the bindApplication() IPC is sent to the process. They're
2410     * lazily setup to make sure the services are running when they're asked for.
2411     */
2412    private HashMap<String, IBinder> getCommonServicesLocked() {
2413        if (mAppBindArgs == null) {
2414            mAppBindArgs = new HashMap<String, IBinder>();
2415
2416            // Setup the application init args
2417            mAppBindArgs.put("package", ServiceManager.getService("package"));
2418            mAppBindArgs.put("window", ServiceManager.getService("window"));
2419            mAppBindArgs.put(Context.ALARM_SERVICE,
2420                    ServiceManager.getService(Context.ALARM_SERVICE));
2421        }
2422        return mAppBindArgs;
2423    }
2424
2425    final void setFocusedActivityLocked(ActivityRecord r) {
2426        if (mFocusedActivity != r) {
2427            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2428            mFocusedActivity = r;
2429            if (r.task != null && r.task.voiceInteractor != null) {
2430                startRunningVoiceLocked();
2431            } else {
2432                finishRunningVoiceLocked();
2433            }
2434            mStackSupervisor.setFocusedStack(r);
2435            if (r != null) {
2436                mWindowManager.setFocusedApp(r.appToken, true);
2437            }
2438            applyUpdateLockStateLocked(r);
2439        }
2440    }
2441
2442    final void clearFocusedActivity(ActivityRecord r) {
2443        if (mFocusedActivity == r) {
2444            mFocusedActivity = null;
2445        }
2446    }
2447
2448    @Override
2449    public void setFocusedStack(int stackId) {
2450        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2451        synchronized (ActivityManagerService.this) {
2452            ActivityStack stack = mStackSupervisor.getStack(stackId);
2453            if (stack != null) {
2454                ActivityRecord r = stack.topRunningActivityLocked(null);
2455                if (r != null) {
2456                    setFocusedActivityLocked(r);
2457                }
2458            }
2459        }
2460    }
2461
2462    @Override
2463    public void notifyActivityDrawn(IBinder token) {
2464        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2465        synchronized (this) {
2466            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2467            if (r != null) {
2468                r.task.stack.notifyActivityDrawnLocked(r);
2469            }
2470        }
2471    }
2472
2473    final void applyUpdateLockStateLocked(ActivityRecord r) {
2474        // Modifications to the UpdateLock state are done on our handler, outside
2475        // the activity manager's locks.  The new state is determined based on the
2476        // state *now* of the relevant activity record.  The object is passed to
2477        // the handler solely for logging detail, not to be consulted/modified.
2478        final boolean nextState = r != null && r.immersive;
2479        mHandler.sendMessage(
2480                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2481    }
2482
2483    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2484        Message msg = Message.obtain();
2485        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2486        msg.obj = r.task.askedCompatMode ? null : r;
2487        mHandler.sendMessage(msg);
2488    }
2489
2490    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2491            String what, Object obj, ProcessRecord srcApp) {
2492        app.lastActivityTime = now;
2493
2494        if (app.activities.size() > 0) {
2495            // Don't want to touch dependent processes that are hosting activities.
2496            return index;
2497        }
2498
2499        int lrui = mLruProcesses.lastIndexOf(app);
2500        if (lrui < 0) {
2501            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2502                    + what + " " + obj + " from " + srcApp);
2503            return index;
2504        }
2505
2506        if (lrui >= index) {
2507            // Don't want to cause this to move dependent processes *back* in the
2508            // list as if they were less frequently used.
2509            return index;
2510        }
2511
2512        if (lrui >= mLruProcessActivityStart) {
2513            // Don't want to touch dependent processes that are hosting activities.
2514            return index;
2515        }
2516
2517        mLruProcesses.remove(lrui);
2518        if (index > 0) {
2519            index--;
2520        }
2521        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2522                + " in LRU list: " + app);
2523        mLruProcesses.add(index, app);
2524        return index;
2525    }
2526
2527    final void removeLruProcessLocked(ProcessRecord app) {
2528        int lrui = mLruProcesses.lastIndexOf(app);
2529        if (lrui >= 0) {
2530            if (lrui <= mLruProcessActivityStart) {
2531                mLruProcessActivityStart--;
2532            }
2533            if (lrui <= mLruProcessServiceStart) {
2534                mLruProcessServiceStart--;
2535            }
2536            mLruProcesses.remove(lrui);
2537        }
2538    }
2539
2540    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2541            ProcessRecord client) {
2542        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2543                || app.treatLikeActivity;
2544        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2545        if (!activityChange && hasActivity) {
2546            // The process has activities, so we are only allowing activity-based adjustments
2547            // to move it.  It should be kept in the front of the list with other
2548            // processes that have activities, and we don't want those to change their
2549            // order except due to activity operations.
2550            return;
2551        }
2552
2553        mLruSeq++;
2554        final long now = SystemClock.uptimeMillis();
2555        app.lastActivityTime = now;
2556
2557        // First a quick reject: if the app is already at the position we will
2558        // put it, then there is nothing to do.
2559        if (hasActivity) {
2560            final int N = mLruProcesses.size();
2561            if (N > 0 && mLruProcesses.get(N-1) == app) {
2562                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2563                return;
2564            }
2565        } else {
2566            if (mLruProcessServiceStart > 0
2567                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2568                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2569                return;
2570            }
2571        }
2572
2573        int lrui = mLruProcesses.lastIndexOf(app);
2574
2575        if (app.persistent && lrui >= 0) {
2576            // We don't care about the position of persistent processes, as long as
2577            // they are in the list.
2578            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2579            return;
2580        }
2581
2582        /* In progress: compute new position first, so we can avoid doing work
2583           if the process is not actually going to move.  Not yet working.
2584        int addIndex;
2585        int nextIndex;
2586        boolean inActivity = false, inService = false;
2587        if (hasActivity) {
2588            // Process has activities, put it at the very tipsy-top.
2589            addIndex = mLruProcesses.size();
2590            nextIndex = mLruProcessServiceStart;
2591            inActivity = true;
2592        } else if (hasService) {
2593            // Process has services, put it at the top of the service list.
2594            addIndex = mLruProcessActivityStart;
2595            nextIndex = mLruProcessServiceStart;
2596            inActivity = true;
2597            inService = true;
2598        } else  {
2599            // Process not otherwise of interest, it goes to the top of the non-service area.
2600            addIndex = mLruProcessServiceStart;
2601            if (client != null) {
2602                int clientIndex = mLruProcesses.lastIndexOf(client);
2603                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2604                        + app);
2605                if (clientIndex >= 0 && addIndex > clientIndex) {
2606                    addIndex = clientIndex;
2607                }
2608            }
2609            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2610        }
2611
2612        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2613                + mLruProcessActivityStart + "): " + app);
2614        */
2615
2616        if (lrui >= 0) {
2617            if (lrui < mLruProcessActivityStart) {
2618                mLruProcessActivityStart--;
2619            }
2620            if (lrui < mLruProcessServiceStart) {
2621                mLruProcessServiceStart--;
2622            }
2623            /*
2624            if (addIndex > lrui) {
2625                addIndex--;
2626            }
2627            if (nextIndex > lrui) {
2628                nextIndex--;
2629            }
2630            */
2631            mLruProcesses.remove(lrui);
2632        }
2633
2634        /*
2635        mLruProcesses.add(addIndex, app);
2636        if (inActivity) {
2637            mLruProcessActivityStart++;
2638        }
2639        if (inService) {
2640            mLruProcessActivityStart++;
2641        }
2642        */
2643
2644        int nextIndex;
2645        if (hasActivity) {
2646            final int N = mLruProcesses.size();
2647            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2648                // Process doesn't have activities, but has clients with
2649                // activities...  move it up, but one below the top (the top
2650                // should always have a real activity).
2651                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2652                mLruProcesses.add(N-1, app);
2653                // To keep it from spamming the LRU list (by making a bunch of clients),
2654                // we will push down any other entries owned by the app.
2655                final int uid = app.info.uid;
2656                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2657                    ProcessRecord subProc = mLruProcesses.get(i);
2658                    if (subProc.info.uid == uid) {
2659                        // We want to push this one down the list.  If the process after
2660                        // it is for the same uid, however, don't do so, because we don't
2661                        // want them internally to be re-ordered.
2662                        if (mLruProcesses.get(i-1).info.uid != uid) {
2663                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2664                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2665                            ProcessRecord tmp = mLruProcesses.get(i);
2666                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2667                            mLruProcesses.set(i-1, tmp);
2668                            i--;
2669                        }
2670                    } else {
2671                        // A gap, we can stop here.
2672                        break;
2673                    }
2674                }
2675            } else {
2676                // Process has activities, put it at the very tipsy-top.
2677                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2678                mLruProcesses.add(app);
2679            }
2680            nextIndex = mLruProcessServiceStart;
2681        } else if (hasService) {
2682            // Process has services, put it at the top of the service list.
2683            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2684            mLruProcesses.add(mLruProcessActivityStart, app);
2685            nextIndex = mLruProcessServiceStart;
2686            mLruProcessActivityStart++;
2687        } else  {
2688            // Process not otherwise of interest, it goes to the top of the non-service area.
2689            int index = mLruProcessServiceStart;
2690            if (client != null) {
2691                // If there is a client, don't allow the process to be moved up higher
2692                // in the list than that client.
2693                int clientIndex = mLruProcesses.lastIndexOf(client);
2694                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2695                        + " when updating " + app);
2696                if (clientIndex <= lrui) {
2697                    // Don't allow the client index restriction to push it down farther in the
2698                    // list than it already is.
2699                    clientIndex = lrui;
2700                }
2701                if (clientIndex >= 0 && index > clientIndex) {
2702                    index = clientIndex;
2703                }
2704            }
2705            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2706            mLruProcesses.add(index, app);
2707            nextIndex = index-1;
2708            mLruProcessActivityStart++;
2709            mLruProcessServiceStart++;
2710        }
2711
2712        // If the app is currently using a content provider or service,
2713        // bump those processes as well.
2714        for (int j=app.connections.size()-1; j>=0; j--) {
2715            ConnectionRecord cr = app.connections.valueAt(j);
2716            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2717                    && cr.binding.service.app != null
2718                    && cr.binding.service.app.lruSeq != mLruSeq
2719                    && !cr.binding.service.app.persistent) {
2720                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2721                        "service connection", cr, app);
2722            }
2723        }
2724        for (int j=app.conProviders.size()-1; j>=0; j--) {
2725            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2726            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2727                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2728                        "provider reference", cpr, app);
2729            }
2730        }
2731    }
2732
2733    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2734        if (uid == Process.SYSTEM_UID) {
2735            // The system gets to run in any process.  If there are multiple
2736            // processes with the same uid, just pick the first (this
2737            // should never happen).
2738            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2739            if (procs == null) return null;
2740            final int N = procs.size();
2741            for (int i = 0; i < N; i++) {
2742                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2743            }
2744        }
2745        ProcessRecord proc = mProcessNames.get(processName, uid);
2746        if (false && proc != null && !keepIfLarge
2747                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2748                && proc.lastCachedPss >= 4000) {
2749            // Turn this condition on to cause killing to happen regularly, for testing.
2750            if (proc.baseProcessTracker != null) {
2751                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2752            }
2753            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2754                    + "k from cached");
2755        } else if (proc != null && !keepIfLarge
2756                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2757                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2758            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2759            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2760                if (proc.baseProcessTracker != null) {
2761                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2762                }
2763                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2764                        + "k from cached");
2765            }
2766        }
2767        return proc;
2768    }
2769
2770    void ensurePackageDexOpt(String packageName) {
2771        IPackageManager pm = AppGlobals.getPackageManager();
2772        try {
2773            if (pm.performDexOpt(packageName)) {
2774                mDidDexOpt = true;
2775            }
2776        } catch (RemoteException e) {
2777        }
2778    }
2779
2780    boolean isNextTransitionForward() {
2781        int transit = mWindowManager.getPendingAppTransition();
2782        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2783                || transit == AppTransition.TRANSIT_TASK_OPEN
2784                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2785    }
2786
2787    final ProcessRecord startProcessLocked(String processName,
2788            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2789            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2790            boolean isolated, boolean keepIfLarge) {
2791        ProcessRecord app;
2792        if (!isolated) {
2793            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2794        } else {
2795            // If this is an isolated process, it can't re-use an existing process.
2796            app = null;
2797        }
2798        // We don't have to do anything more if:
2799        // (1) There is an existing application record; and
2800        // (2) The caller doesn't think it is dead, OR there is no thread
2801        //     object attached to it so we know it couldn't have crashed; and
2802        // (3) There is a pid assigned to it, so it is either starting or
2803        //     already running.
2804        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2805                + " app=" + app + " knownToBeDead=" + knownToBeDead
2806                + " thread=" + (app != null ? app.thread : null)
2807                + " pid=" + (app != null ? app.pid : -1));
2808        if (app != null && app.pid > 0) {
2809            if (!knownToBeDead || app.thread == null) {
2810                // We already have the app running, or are waiting for it to
2811                // come up (we have a pid but not yet its thread), so keep it.
2812                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2813                // If this is a new package in the process, add the package to the list
2814                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2815                return app;
2816            }
2817
2818            // An application record is attached to a previous process,
2819            // clean it up now.
2820            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2821            handleAppDiedLocked(app, true, true);
2822        }
2823
2824        String hostingNameStr = hostingName != null
2825                ? hostingName.flattenToShortString() : null;
2826
2827        if (!isolated) {
2828            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2829                // If we are in the background, then check to see if this process
2830                // is bad.  If so, we will just silently fail.
2831                if (mBadProcesses.get(info.processName, info.uid) != null) {
2832                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2833                            + "/" + info.processName);
2834                    return null;
2835                }
2836            } else {
2837                // When the user is explicitly starting a process, then clear its
2838                // crash count so that we won't make it bad until they see at
2839                // least one crash dialog again, and make the process good again
2840                // if it had been bad.
2841                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2842                        + "/" + info.processName);
2843                mProcessCrashTimes.remove(info.processName, info.uid);
2844                if (mBadProcesses.get(info.processName, info.uid) != null) {
2845                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2846                            UserHandle.getUserId(info.uid), info.uid,
2847                            info.processName);
2848                    mBadProcesses.remove(info.processName, info.uid);
2849                    if (app != null) {
2850                        app.bad = false;
2851                    }
2852                }
2853            }
2854        }
2855
2856        if (app == null) {
2857            app = newProcessRecordLocked(info, processName, isolated);
2858            if (app == null) {
2859                Slog.w(TAG, "Failed making new process record for "
2860                        + processName + "/" + info.uid + " isolated=" + isolated);
2861                return null;
2862            }
2863            mProcessNames.put(processName, app.uid, app);
2864            if (isolated) {
2865                mIsolatedProcesses.put(app.uid, app);
2866            }
2867        } else {
2868            // If this is a new package in the process, add the package to the list
2869            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2870        }
2871
2872        // If the system is not ready yet, then hold off on starting this
2873        // process until it is.
2874        if (!mProcessesReady
2875                && !isAllowedWhileBooting(info)
2876                && !allowWhileBooting) {
2877            if (!mProcessesOnHold.contains(app)) {
2878                mProcessesOnHold.add(app);
2879            }
2880            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2881            return app;
2882        }
2883
2884        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2885        return (app.pid != 0) ? app : null;
2886    }
2887
2888    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2889        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2890    }
2891
2892    private final void startProcessLocked(ProcessRecord app,
2893            String hostingType, String hostingNameStr, String abiOverride) {
2894        if (app.pid > 0 && app.pid != MY_PID) {
2895            synchronized (mPidsSelfLocked) {
2896                mPidsSelfLocked.remove(app.pid);
2897                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2898            }
2899            app.setPid(0);
2900        }
2901
2902        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2903                "startProcessLocked removing on hold: " + app);
2904        mProcessesOnHold.remove(app);
2905
2906        updateCpuStats();
2907
2908        try {
2909            int uid = app.uid;
2910
2911            int[] gids = null;
2912            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2913            if (!app.isolated) {
2914                int[] permGids = null;
2915                try {
2916                    final PackageManager pm = mContext.getPackageManager();
2917                    permGids = pm.getPackageGids(app.info.packageName);
2918
2919                    if (Environment.isExternalStorageEmulated()) {
2920                        if (pm.checkPermission(
2921                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2922                                app.info.packageName) == PERMISSION_GRANTED) {
2923                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2924                        } else {
2925                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2926                        }
2927                    }
2928                } catch (PackageManager.NameNotFoundException e) {
2929                    Slog.w(TAG, "Unable to retrieve gids", e);
2930                }
2931
2932                /*
2933                 * Add shared application and profile GIDs so applications can share some
2934                 * resources like shared libraries and access user-wide resources
2935                 */
2936                if (permGids == null) {
2937                    gids = new int[2];
2938                } else {
2939                    gids = new int[permGids.length + 2];
2940                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2941                }
2942                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2943                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2944            }
2945            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2946                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2947                        && mTopComponent != null
2948                        && app.processName.equals(mTopComponent.getPackageName())) {
2949                    uid = 0;
2950                }
2951                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2952                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2953                    uid = 0;
2954                }
2955            }
2956            int debugFlags = 0;
2957            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2958                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2959                // Also turn on CheckJNI for debuggable apps. It's quite
2960                // awkward to turn on otherwise.
2961                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2962            }
2963            // Run the app in safe mode if its manifest requests so or the
2964            // system is booted in safe mode.
2965            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2966                mSafeMode == true) {
2967                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2968            }
2969            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2970                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2971            }
2972            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2973                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2974            }
2975            if ("1".equals(SystemProperties.get("debug.assert"))) {
2976                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2977            }
2978
2979            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2980            if (requiredAbi == null) {
2981                requiredAbi = Build.SUPPORTED_ABIS[0];
2982            }
2983
2984            // Start the process.  It will either succeed and return a result containing
2985            // the PID of the new process, or else throw a RuntimeException.
2986            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2987                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2988                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2989
2990            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2991            synchronized (bs) {
2992                if (bs.isOnBattery()) {
2993                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2994                }
2995            }
2996
2997            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2998                    UserHandle.getUserId(uid), startResult.pid, uid,
2999                    app.processName, hostingType,
3000                    hostingNameStr != null ? hostingNameStr : "");
3001
3002            if (app.persistent) {
3003                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3004            }
3005
3006            StringBuilder buf = mStringBuilder;
3007            buf.setLength(0);
3008            buf.append("Start proc ");
3009            buf.append(app.processName);
3010            buf.append(" for ");
3011            buf.append(hostingType);
3012            if (hostingNameStr != null) {
3013                buf.append(" ");
3014                buf.append(hostingNameStr);
3015            }
3016            buf.append(": pid=");
3017            buf.append(startResult.pid);
3018            buf.append(" uid=");
3019            buf.append(uid);
3020            buf.append(" gids={");
3021            if (gids != null) {
3022                for (int gi=0; gi<gids.length; gi++) {
3023                    if (gi != 0) buf.append(", ");
3024                    buf.append(gids[gi]);
3025
3026                }
3027            }
3028            buf.append("}");
3029            if (requiredAbi != null) {
3030                buf.append(" abi=");
3031                buf.append(requiredAbi);
3032            }
3033            Slog.i(TAG, buf.toString());
3034            app.setPid(startResult.pid);
3035            app.usingWrapper = startResult.usingWrapper;
3036            app.removed = false;
3037            synchronized (mPidsSelfLocked) {
3038                this.mPidsSelfLocked.put(startResult.pid, app);
3039                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3040                msg.obj = app;
3041                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3042                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3043            }
3044            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3045                    app.processName, app.info.uid);
3046            if (app.isolated) {
3047                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3048            }
3049        } catch (RuntimeException e) {
3050            // XXX do better error recovery.
3051            app.setPid(0);
3052            Slog.e(TAG, "Failure starting process " + app.processName, e);
3053        }
3054    }
3055
3056    void updateUsageStats(ActivityRecord component, boolean resumed) {
3057        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3058        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3059        if (resumed) {
3060            mUsageStatsService.noteResumeComponent(component.realActivity);
3061            synchronized (stats) {
3062                stats.noteActivityResumedLocked(component.app.uid);
3063            }
3064        } else {
3065            mUsageStatsService.notePauseComponent(component.realActivity);
3066            synchronized (stats) {
3067                stats.noteActivityPausedLocked(component.app.uid);
3068            }
3069        }
3070    }
3071
3072    Intent getHomeIntent() {
3073        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3074        intent.setComponent(mTopComponent);
3075        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3076            intent.addCategory(Intent.CATEGORY_HOME);
3077        }
3078        return intent;
3079    }
3080
3081    boolean startHomeActivityLocked(int userId) {
3082        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3083                && mTopAction == null) {
3084            // We are running in factory test mode, but unable to find
3085            // the factory test app, so just sit around displaying the
3086            // error message and don't try to start anything.
3087            return false;
3088        }
3089        Intent intent = getHomeIntent();
3090        ActivityInfo aInfo =
3091            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3092        if (aInfo != null) {
3093            intent.setComponent(new ComponentName(
3094                    aInfo.applicationInfo.packageName, aInfo.name));
3095            // Don't do this if the home app is currently being
3096            // instrumented.
3097            aInfo = new ActivityInfo(aInfo);
3098            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3099            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3100                    aInfo.applicationInfo.uid, true);
3101            if (app == null || app.instrumentationClass == null) {
3102                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3103                mStackSupervisor.startHomeActivity(intent, aInfo);
3104            }
3105        }
3106
3107        return true;
3108    }
3109
3110    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3111        ActivityInfo ai = null;
3112        ComponentName comp = intent.getComponent();
3113        try {
3114            if (comp != null) {
3115                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3116            } else {
3117                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3118                        intent,
3119                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3120                            flags, userId);
3121
3122                if (info != null) {
3123                    ai = info.activityInfo;
3124                }
3125            }
3126        } catch (RemoteException e) {
3127            // ignore
3128        }
3129
3130        return ai;
3131    }
3132
3133    /**
3134     * Starts the "new version setup screen" if appropriate.
3135     */
3136    void startSetupActivityLocked() {
3137        // Only do this once per boot.
3138        if (mCheckedForSetup) {
3139            return;
3140        }
3141
3142        // We will show this screen if the current one is a different
3143        // version than the last one shown, and we are not running in
3144        // low-level factory test mode.
3145        final ContentResolver resolver = mContext.getContentResolver();
3146        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3147                Settings.Global.getInt(resolver,
3148                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3149            mCheckedForSetup = true;
3150
3151            // See if we should be showing the platform update setup UI.
3152            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3153            List<ResolveInfo> ris = mContext.getPackageManager()
3154                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3155
3156            // We don't allow third party apps to replace this.
3157            ResolveInfo ri = null;
3158            for (int i=0; ris != null && i<ris.size(); i++) {
3159                if ((ris.get(i).activityInfo.applicationInfo.flags
3160                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3161                    ri = ris.get(i);
3162                    break;
3163                }
3164            }
3165
3166            if (ri != null) {
3167                String vers = ri.activityInfo.metaData != null
3168                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3169                        : null;
3170                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3171                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3172                            Intent.METADATA_SETUP_VERSION);
3173                }
3174                String lastVers = Settings.Secure.getString(
3175                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3176                if (vers != null && !vers.equals(lastVers)) {
3177                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3178                    intent.setComponent(new ComponentName(
3179                            ri.activityInfo.packageName, ri.activityInfo.name));
3180                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3181                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3182                }
3183            }
3184        }
3185    }
3186
3187    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3188        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3189    }
3190
3191    void enforceNotIsolatedCaller(String caller) {
3192        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3193            throw new SecurityException("Isolated process not allowed to call " + caller);
3194        }
3195    }
3196
3197    @Override
3198    public int getFrontActivityScreenCompatMode() {
3199        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3200        synchronized (this) {
3201            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3202        }
3203    }
3204
3205    @Override
3206    public void setFrontActivityScreenCompatMode(int mode) {
3207        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3208                "setFrontActivityScreenCompatMode");
3209        synchronized (this) {
3210            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3211        }
3212    }
3213
3214    @Override
3215    public int getPackageScreenCompatMode(String packageName) {
3216        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3217        synchronized (this) {
3218            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3219        }
3220    }
3221
3222    @Override
3223    public void setPackageScreenCompatMode(String packageName, int mode) {
3224        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3225                "setPackageScreenCompatMode");
3226        synchronized (this) {
3227            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3228        }
3229    }
3230
3231    @Override
3232    public boolean getPackageAskScreenCompat(String packageName) {
3233        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3234        synchronized (this) {
3235            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3236        }
3237    }
3238
3239    @Override
3240    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3241        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3242                "setPackageAskScreenCompat");
3243        synchronized (this) {
3244            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3245        }
3246    }
3247
3248    private void dispatchProcessesChanged() {
3249        int N;
3250        synchronized (this) {
3251            N = mPendingProcessChanges.size();
3252            if (mActiveProcessChanges.length < N) {
3253                mActiveProcessChanges = new ProcessChangeItem[N];
3254            }
3255            mPendingProcessChanges.toArray(mActiveProcessChanges);
3256            mAvailProcessChanges.addAll(mPendingProcessChanges);
3257            mPendingProcessChanges.clear();
3258            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3259        }
3260
3261        int i = mProcessObservers.beginBroadcast();
3262        while (i > 0) {
3263            i--;
3264            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3265            if (observer != null) {
3266                try {
3267                    for (int j=0; j<N; j++) {
3268                        ProcessChangeItem item = mActiveProcessChanges[j];
3269                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3270                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3271                                    + item.pid + " uid=" + item.uid + ": "
3272                                    + item.foregroundActivities);
3273                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3274                                    item.foregroundActivities);
3275                        }
3276                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3277                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3278                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3279                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3280                        }
3281                    }
3282                } catch (RemoteException e) {
3283                }
3284            }
3285        }
3286        mProcessObservers.finishBroadcast();
3287    }
3288
3289    private void dispatchProcessDied(int pid, int uid) {
3290        int i = mProcessObservers.beginBroadcast();
3291        while (i > 0) {
3292            i--;
3293            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3294            if (observer != null) {
3295                try {
3296                    observer.onProcessDied(pid, uid);
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    final void doPendingActivityLaunchesLocked(boolean doResume) {
3305        final int N = mPendingActivityLaunches.size();
3306        if (N <= 0) {
3307            return;
3308        }
3309        for (int i=0; i<N; i++) {
3310            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3311            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3312                    doResume && i == (N-1), null);
3313        }
3314        mPendingActivityLaunches.clear();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo,
3320            String resultWho, int requestCode, int startFlags,
3321            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3322        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3323                resultWho, requestCode,
3324                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3325    }
3326
3327    @Override
3328    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3329            Intent intent, String resolvedType, IBinder resultTo,
3330            String resultWho, int requestCode, int startFlags,
3331            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3332        enforceNotIsolatedCaller("startActivity");
3333        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3334                false, true, "startActivity", null);
3335        // TODO: Switch to user app stacks here.
3336        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3337                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3338                null, null, options, userId, null);
3339    }
3340
3341    @Override
3342    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo,
3344            String resultWho, int requestCode, int startFlags, String profileFile,
3345            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3346        enforceNotIsolatedCaller("startActivityAndWait");
3347        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3348                false, true, "startActivityAndWait", null);
3349        WaitResult res = new WaitResult();
3350        // TODO: Switch to user app stacks here.
3351        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3352                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3353                res, null, options, UserHandle.getCallingUserId(), null);
3354        return res;
3355    }
3356
3357    @Override
3358    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags, Configuration config,
3361            Bundle options, int userId) {
3362        enforceNotIsolatedCaller("startActivityWithConfig");
3363        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3364                false, true, "startActivityWithConfig", null);
3365        // TODO: Switch to user app stacks here.
3366        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3367                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3368                null, null, null, config, options, userId, null);
3369        return ret;
3370    }
3371
3372    @Override
3373    public int startActivityIntentSender(IApplicationThread caller,
3374            IntentSender intent, Intent fillInIntent, String resolvedType,
3375            IBinder resultTo, String resultWho, int requestCode,
3376            int flagsMask, int flagsValues, Bundle options) {
3377        enforceNotIsolatedCaller("startActivityIntentSender");
3378        // Refuse possible leaked file descriptors
3379        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3380            throw new IllegalArgumentException("File descriptors passed in Intent");
3381        }
3382
3383        IIntentSender sender = intent.getTarget();
3384        if (!(sender instanceof PendingIntentRecord)) {
3385            throw new IllegalArgumentException("Bad PendingIntent object");
3386        }
3387
3388        PendingIntentRecord pir = (PendingIntentRecord)sender;
3389
3390        synchronized (this) {
3391            // If this is coming from the currently resumed activity, it is
3392            // effectively saying that app switches are allowed at this point.
3393            final ActivityStack stack = getFocusedStack();
3394            if (stack.mResumedActivity != null &&
3395                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3396                mAppSwitchesAllowedTime = 0;
3397            }
3398        }
3399        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3400                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3401        return ret;
3402    }
3403
3404    @Override
3405    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3406            Intent intent, String resolvedType, IVoiceInteractionSession session,
3407            IVoiceInteractor interactor, int startFlags, String profileFile,
3408            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3409        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3410                != PackageManager.PERMISSION_GRANTED) {
3411            String msg = "Permission Denial: startVoiceActivity() from pid="
3412                    + Binder.getCallingPid()
3413                    + ", uid=" + Binder.getCallingUid()
3414                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3415            Slog.w(TAG, msg);
3416            throw new SecurityException(msg);
3417        }
3418        if (session == null || interactor == null) {
3419            throw new NullPointerException("null session or interactor");
3420        }
3421        userId = handleIncomingUser(callingPid, callingUid, userId,
3422                false, true, "startVoiceActivity", null);
3423        // TODO: Switch to user app stacks here.
3424        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3425                resolvedType, session, interactor, null, null, 0, startFlags,
3426                profileFile, profileFd, null, null, options, userId, null);
3427    }
3428
3429    @Override
3430    public boolean startNextMatchingActivity(IBinder callingActivity,
3431            Intent intent, Bundle options) {
3432        // Refuse possible leaked file descriptors
3433        if (intent != null && intent.hasFileDescriptors() == true) {
3434            throw new IllegalArgumentException("File descriptors passed in Intent");
3435        }
3436
3437        synchronized (this) {
3438            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3439            if (r == null) {
3440                ActivityOptions.abort(options);
3441                return false;
3442            }
3443            if (r.app == null || r.app.thread == null) {
3444                // The caller is not running...  d'oh!
3445                ActivityOptions.abort(options);
3446                return false;
3447            }
3448            intent = new Intent(intent);
3449            // The caller is not allowed to change the data.
3450            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3451            // And we are resetting to find the next component...
3452            intent.setComponent(null);
3453
3454            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3455
3456            ActivityInfo aInfo = null;
3457            try {
3458                List<ResolveInfo> resolves =
3459                    AppGlobals.getPackageManager().queryIntentActivities(
3460                            intent, r.resolvedType,
3461                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3462                            UserHandle.getCallingUserId());
3463
3464                // Look for the original activity in the list...
3465                final int N = resolves != null ? resolves.size() : 0;
3466                for (int i=0; i<N; i++) {
3467                    ResolveInfo rInfo = resolves.get(i);
3468                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3469                            && rInfo.activityInfo.name.equals(r.info.name)) {
3470                        // We found the current one...  the next matching is
3471                        // after it.
3472                        i++;
3473                        if (i<N) {
3474                            aInfo = resolves.get(i).activityInfo;
3475                        }
3476                        if (debug) {
3477                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3478                                    + "/" + r.info.name);
3479                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3480                                    + "/" + aInfo.name);
3481                        }
3482                        break;
3483                    }
3484                }
3485            } catch (RemoteException e) {
3486            }
3487
3488            if (aInfo == null) {
3489                // Nobody who is next!
3490                ActivityOptions.abort(options);
3491                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3492                return false;
3493            }
3494
3495            intent.setComponent(new ComponentName(
3496                    aInfo.applicationInfo.packageName, aInfo.name));
3497            intent.setFlags(intent.getFlags()&~(
3498                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3499                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3500                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3501                    Intent.FLAG_ACTIVITY_NEW_TASK));
3502
3503            // Okay now we need to start the new activity, replacing the
3504            // currently running activity.  This is a little tricky because
3505            // we want to start the new one as if the current one is finished,
3506            // but not finish the current one first so that there is no flicker.
3507            // And thus...
3508            final boolean wasFinishing = r.finishing;
3509            r.finishing = true;
3510
3511            // Propagate reply information over to the new activity.
3512            final ActivityRecord resultTo = r.resultTo;
3513            final String resultWho = r.resultWho;
3514            final int requestCode = r.requestCode;
3515            r.resultTo = null;
3516            if (resultTo != null) {
3517                resultTo.removeResultsLocked(r, resultWho, requestCode);
3518            }
3519
3520            final long origId = Binder.clearCallingIdentity();
3521            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3522                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3523                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3524                    options, false, null, null);
3525            Binder.restoreCallingIdentity(origId);
3526
3527            r.finishing = wasFinishing;
3528            if (res != ActivityManager.START_SUCCESS) {
3529                return false;
3530            }
3531            return true;
3532        }
3533    }
3534
3535    final int startActivityInPackage(int uid, String callingPackage,
3536            Intent intent, String resolvedType, IBinder resultTo,
3537            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3538                    IActivityContainer container) {
3539
3540        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3541                false, true, "startActivityInPackage", null);
3542
3543        // TODO: Switch to user app stacks here.
3544        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3545                null, null, resultTo, resultWho, requestCode, startFlags,
3546                null, null, null, null, options, userId, container);
3547        return ret;
3548    }
3549
3550    @Override
3551    public final int startActivities(IApplicationThread caller, String callingPackage,
3552            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3553            int userId) {
3554        enforceNotIsolatedCaller("startActivities");
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, true, "startActivity", null);
3557        // TODO: Switch to user app stacks here.
3558        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3559                resolvedTypes, resultTo, options, userId);
3560        return ret;
3561    }
3562
3563    final int startActivitiesInPackage(int uid, String callingPackage,
3564            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3565            Bundle options, int userId) {
3566
3567        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3568                false, true, "startActivityInPackage", null);
3569        // TODO: Switch to user app stacks here.
3570        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3571                resultTo, options, userId);
3572        return ret;
3573    }
3574
3575    final void addRecentTaskLocked(TaskRecord task) {
3576        int N = mRecentTasks.size();
3577        // Quick case: check if the top-most recent task is the same.
3578        if (N > 0 && mRecentTasks.get(0) == task) {
3579            return;
3580        }
3581        // Another quick case: never add voice sessions.
3582        if (task.voiceSession != null) {
3583            return;
3584        }
3585        // Remove any existing entries that are the same kind of task.
3586        final Intent intent = task.intent;
3587        final boolean document = intent != null && intent.isDocument();
3588        final ComponentName comp = intent.getComponent();
3589
3590        int maxRecents = task.maxRecents - 1;
3591        for (int i=0; i<N; i++) {
3592            TaskRecord tr = mRecentTasks.get(i);
3593            if (task != tr) {
3594                if (task.userId != tr.userId) {
3595                    continue;
3596                }
3597                final Intent trIntent = tr.intent;
3598                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3599                    (intent == null || !intent.filterEquals(trIntent))) {
3600                    continue;
3601                }
3602                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3603                if (document && trIsDocument) {
3604                    // These are the same document activity (not necessarily the same doc).
3605                    if (maxRecents > 0) {
3606                        --maxRecents;
3607                        continue;
3608                    }
3609                    // Hit the maximum number of documents for this task. Fall through
3610                    // and remove this document from recents.
3611                } else if (document || trIsDocument) {
3612                    // Only one of these is a document. Not the droid we're looking for.
3613                    continue;
3614                }
3615            }
3616
3617            // Either task and tr are the same or, their affinities match or their intents match
3618            // and neither of them is a document, or they are documents using the same activity
3619            // and their maxRecents has been reached.
3620            tr.disposeThumbnail();
3621            mRecentTasks.remove(i);
3622            i--;
3623            N--;
3624            if (task.intent == null) {
3625                // If the new recent task we are adding is not fully
3626                // specified, then replace it with the existing recent task.
3627                task = tr;
3628            }
3629            mTaskPersister.notify(tr, false);
3630        }
3631        if (N >= MAX_RECENT_TASKS) {
3632            mRecentTasks.remove(N-1).disposeThumbnail();
3633        }
3634        mRecentTasks.add(0, task);
3635    }
3636
3637    @Override
3638    public void reportActivityFullyDrawn(IBinder token) {
3639        synchronized (this) {
3640            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3641            if (r == null) {
3642                return;
3643            }
3644            r.reportFullyDrawnLocked();
3645        }
3646    }
3647
3648    @Override
3649    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3650        synchronized (this) {
3651            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3652            if (r == null) {
3653                return;
3654            }
3655            final long origId = Binder.clearCallingIdentity();
3656            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3657            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3658                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3659            if (config != null) {
3660                r.frozenBeforeDestroy = true;
3661                if (!updateConfigurationLocked(config, r, false, false)) {
3662                    mStackSupervisor.resumeTopActivitiesLocked();
3663                }
3664            }
3665            Binder.restoreCallingIdentity(origId);
3666        }
3667    }
3668
3669    @Override
3670    public int getRequestedOrientation(IBinder token) {
3671        synchronized (this) {
3672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3673            if (r == null) {
3674                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3675            }
3676            return mWindowManager.getAppOrientation(r.appToken);
3677        }
3678    }
3679
3680    /**
3681     * This is the internal entry point for handling Activity.finish().
3682     *
3683     * @param token The Binder token referencing the Activity we want to finish.
3684     * @param resultCode Result code, if any, from this Activity.
3685     * @param resultData Result data (Intent), if any, from this Activity.
3686     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3687     *            the root Activity in the task.
3688     *
3689     * @return Returns true if the activity successfully finished, or false if it is still running.
3690     */
3691    @Override
3692    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3693            boolean finishTask) {
3694        // Refuse possible leaked file descriptors
3695        if (resultData != null && resultData.hasFileDescriptors() == true) {
3696            throw new IllegalArgumentException("File descriptors passed in Intent");
3697        }
3698
3699        synchronized(this) {
3700            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3701            if (r == null) {
3702                return true;
3703            }
3704            // Keep track of the root activity of the task before we finish it
3705            TaskRecord tr = r.task;
3706            ActivityRecord rootR = tr.getRootActivity();
3707            if (mController != null) {
3708                // Find the first activity that is not finishing.
3709                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3710                if (next != null) {
3711                    // ask watcher if this is allowed
3712                    boolean resumeOK = true;
3713                    try {
3714                        resumeOK = mController.activityResuming(next.packageName);
3715                    } catch (RemoteException e) {
3716                        mController = null;
3717                        Watchdog.getInstance().setActivityController(null);
3718                    }
3719
3720                    if (!resumeOK) {
3721                        return false;
3722                    }
3723                }
3724            }
3725            final long origId = Binder.clearCallingIdentity();
3726            try {
3727                boolean res;
3728                if (finishTask && r == rootR) {
3729                    // If requested, remove the task that is associated to this activity only if it
3730                    // was the root activity in the task.  The result code and data is ignored because
3731                    // we don't support returning them across task boundaries.
3732                    res = removeTaskByIdLocked(tr.taskId, 0);
3733                } else {
3734                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3735                            resultData, "app-request", true);
3736                }
3737                return res;
3738            } finally {
3739                Binder.restoreCallingIdentity(origId);
3740            }
3741        }
3742    }
3743
3744    @Override
3745    public final void finishHeavyWeightApp() {
3746        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3747                != PackageManager.PERMISSION_GRANTED) {
3748            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3749                    + Binder.getCallingPid()
3750                    + ", uid=" + Binder.getCallingUid()
3751                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3752            Slog.w(TAG, msg);
3753            throw new SecurityException(msg);
3754        }
3755
3756        synchronized(this) {
3757            if (mHeavyWeightProcess == null) {
3758                return;
3759            }
3760
3761            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3762                    mHeavyWeightProcess.activities);
3763            for (int i=0; i<activities.size(); i++) {
3764                ActivityRecord r = activities.get(i);
3765                if (!r.finishing) {
3766                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3767                            null, "finish-heavy", true);
3768                }
3769            }
3770
3771            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3772                    mHeavyWeightProcess.userId, 0));
3773            mHeavyWeightProcess = null;
3774        }
3775    }
3776
3777    @Override
3778    public void crashApplication(int uid, int initialPid, String packageName,
3779            String message) {
3780        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3781                != PackageManager.PERMISSION_GRANTED) {
3782            String msg = "Permission Denial: crashApplication() from pid="
3783                    + Binder.getCallingPid()
3784                    + ", uid=" + Binder.getCallingUid()
3785                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3786            Slog.w(TAG, msg);
3787            throw new SecurityException(msg);
3788        }
3789
3790        synchronized(this) {
3791            ProcessRecord proc = null;
3792
3793            // Figure out which process to kill.  We don't trust that initialPid
3794            // still has any relation to current pids, so must scan through the
3795            // list.
3796            synchronized (mPidsSelfLocked) {
3797                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3798                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3799                    if (p.uid != uid) {
3800                        continue;
3801                    }
3802                    if (p.pid == initialPid) {
3803                        proc = p;
3804                        break;
3805                    }
3806                    if (p.pkgList.containsKey(packageName)) {
3807                        proc = p;
3808                    }
3809                }
3810            }
3811
3812            if (proc == null) {
3813                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3814                        + " initialPid=" + initialPid
3815                        + " packageName=" + packageName);
3816                return;
3817            }
3818
3819            if (proc.thread != null) {
3820                if (proc.pid == Process.myPid()) {
3821                    Log.w(TAG, "crashApplication: trying to crash self!");
3822                    return;
3823                }
3824                long ident = Binder.clearCallingIdentity();
3825                try {
3826                    proc.thread.scheduleCrash(message);
3827                } catch (RemoteException e) {
3828                }
3829                Binder.restoreCallingIdentity(ident);
3830            }
3831        }
3832    }
3833
3834    @Override
3835    public final void finishSubActivity(IBinder token, String resultWho,
3836            int requestCode) {
3837        synchronized(this) {
3838            final long origId = Binder.clearCallingIdentity();
3839            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3840            if (r != null) {
3841                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3842            }
3843            Binder.restoreCallingIdentity(origId);
3844        }
3845    }
3846
3847    @Override
3848    public boolean finishActivityAffinity(IBinder token) {
3849        synchronized(this) {
3850            final long origId = Binder.clearCallingIdentity();
3851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3852            boolean res = false;
3853            if (r != null) {
3854                res = r.task.stack.finishActivityAffinityLocked(r);
3855            }
3856            Binder.restoreCallingIdentity(origId);
3857            return res;
3858        }
3859    }
3860
3861    @Override
3862    public boolean willActivityBeVisible(IBinder token) {
3863        synchronized(this) {
3864            ActivityStack stack = ActivityRecord.getStackLocked(token);
3865            if (stack != null) {
3866                return stack.willActivityBeVisibleLocked(token);
3867            }
3868            return false;
3869        }
3870    }
3871
3872    @Override
3873    public void overridePendingTransition(IBinder token, String packageName,
3874            int enterAnim, int exitAnim) {
3875        synchronized(this) {
3876            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3877            if (self == null) {
3878                return;
3879            }
3880
3881            final long origId = Binder.clearCallingIdentity();
3882
3883            if (self.state == ActivityState.RESUMED
3884                    || self.state == ActivityState.PAUSING) {
3885                mWindowManager.overridePendingAppTransition(packageName,
3886                        enterAnim, exitAnim, null);
3887            }
3888
3889            Binder.restoreCallingIdentity(origId);
3890        }
3891    }
3892
3893    /**
3894     * Main function for removing an existing process from the activity manager
3895     * as a result of that process going away.  Clears out all connections
3896     * to the process.
3897     */
3898    private final void handleAppDiedLocked(ProcessRecord app,
3899            boolean restarting, boolean allowRestart) {
3900        int pid = app.pid;
3901        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3902        if (!restarting) {
3903            removeLruProcessLocked(app);
3904            if (pid > 0) {
3905                ProcessList.remove(pid);
3906            }
3907        }
3908
3909        if (mProfileProc == app) {
3910            clearProfilerLocked();
3911        }
3912
3913        // Remove this application's activities from active lists.
3914        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3915
3916        app.activities.clear();
3917
3918        if (app.instrumentationClass != null) {
3919            Slog.w(TAG, "Crash of app " + app.processName
3920                  + " running instrumentation " + app.instrumentationClass);
3921            Bundle info = new Bundle();
3922            info.putString("shortMsg", "Process crashed.");
3923            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3924        }
3925
3926        if (!restarting) {
3927            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3928                // If there was nothing to resume, and we are not already
3929                // restarting this process, but there is a visible activity that
3930                // is hosted by the process...  then make sure all visible
3931                // activities are running, taking care of restarting this
3932                // process.
3933                if (hasVisibleActivities) {
3934                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3935                }
3936            }
3937        }
3938    }
3939
3940    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3941        IBinder threadBinder = thread.asBinder();
3942        // Find the application record.
3943        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3944            ProcessRecord rec = mLruProcesses.get(i);
3945            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3946                return i;
3947            }
3948        }
3949        return -1;
3950    }
3951
3952    final ProcessRecord getRecordForAppLocked(
3953            IApplicationThread thread) {
3954        if (thread == null) {
3955            return null;
3956        }
3957
3958        int appIndex = getLRURecordIndexForAppLocked(thread);
3959        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3960    }
3961
3962    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3963        // If there are no longer any background processes running,
3964        // and the app that died was not running instrumentation,
3965        // then tell everyone we are now low on memory.
3966        boolean haveBg = false;
3967        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3968            ProcessRecord rec = mLruProcesses.get(i);
3969            if (rec.thread != null
3970                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3971                haveBg = true;
3972                break;
3973            }
3974        }
3975
3976        if (!haveBg) {
3977            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3978            if (doReport) {
3979                long now = SystemClock.uptimeMillis();
3980                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3981                    doReport = false;
3982                } else {
3983                    mLastMemUsageReportTime = now;
3984                }
3985            }
3986            final ArrayList<ProcessMemInfo> memInfos
3987                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3988            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3989            long now = SystemClock.uptimeMillis();
3990            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3991                ProcessRecord rec = mLruProcesses.get(i);
3992                if (rec == dyingProc || rec.thread == null) {
3993                    continue;
3994                }
3995                if (doReport) {
3996                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3997                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3998                }
3999                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4000                    // The low memory report is overriding any current
4001                    // state for a GC request.  Make sure to do
4002                    // heavy/important/visible/foreground processes first.
4003                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4004                        rec.lastRequestedGc = 0;
4005                    } else {
4006                        rec.lastRequestedGc = rec.lastLowMemory;
4007                    }
4008                    rec.reportLowMemory = true;
4009                    rec.lastLowMemory = now;
4010                    mProcessesToGc.remove(rec);
4011                    addProcessToGcListLocked(rec);
4012                }
4013            }
4014            if (doReport) {
4015                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4016                mHandler.sendMessage(msg);
4017            }
4018            scheduleAppGcsLocked();
4019        }
4020    }
4021
4022    final void appDiedLocked(ProcessRecord app, int pid,
4023            IApplicationThread thread) {
4024
4025        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4026        synchronized (stats) {
4027            stats.noteProcessDiedLocked(app.info.uid, pid);
4028        }
4029
4030        // Clean up already done if the process has been re-started.
4031        if (app.pid == pid && app.thread != null &&
4032                app.thread.asBinder() == thread.asBinder()) {
4033            boolean doLowMem = app.instrumentationClass == null;
4034            boolean doOomAdj = doLowMem;
4035            if (!app.killedByAm) {
4036                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4037                        + ") has died.");
4038                mAllowLowerMemLevel = true;
4039            } else {
4040                // Note that we always want to do oom adj to update our state with the
4041                // new number of procs.
4042                mAllowLowerMemLevel = false;
4043                doLowMem = false;
4044            }
4045            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4046            if (DEBUG_CLEANUP) Slog.v(
4047                TAG, "Dying app: " + app + ", pid: " + pid
4048                + ", thread: " + thread.asBinder());
4049            handleAppDiedLocked(app, false, true);
4050
4051            if (doOomAdj) {
4052                updateOomAdjLocked();
4053            }
4054            if (doLowMem) {
4055                doLowMemReportIfNeededLocked(app);
4056            }
4057        } else if (app.pid != pid) {
4058            // A new process has already been started.
4059            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4060                    + ") has died and restarted (pid " + app.pid + ").");
4061            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4062        } else if (DEBUG_PROCESSES) {
4063            Slog.d(TAG, "Received spurious death notification for thread "
4064                    + thread.asBinder());
4065        }
4066    }
4067
4068    /**
4069     * If a stack trace dump file is configured, dump process stack traces.
4070     * @param clearTraces causes the dump file to be erased prior to the new
4071     *    traces being written, if true; when false, the new traces will be
4072     *    appended to any existing file content.
4073     * @param firstPids of dalvik VM processes to dump stack traces for first
4074     * @param lastPids of dalvik VM processes to dump stack traces for last
4075     * @param nativeProcs optional list of native process names to dump stack crawls
4076     * @return file containing stack traces, or null if no dump file is configured
4077     */
4078    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4079            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4080        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4081        if (tracesPath == null || tracesPath.length() == 0) {
4082            return null;
4083        }
4084
4085        File tracesFile = new File(tracesPath);
4086        try {
4087            File tracesDir = tracesFile.getParentFile();
4088            if (!tracesDir.exists()) {
4089                tracesFile.mkdirs();
4090                if (!SELinux.restorecon(tracesDir)) {
4091                    return null;
4092                }
4093            }
4094            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4095
4096            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4097            tracesFile.createNewFile();
4098            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4099        } catch (IOException e) {
4100            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4101            return null;
4102        }
4103
4104        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4105        return tracesFile;
4106    }
4107
4108    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4109            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4110        // Use a FileObserver to detect when traces finish writing.
4111        // The order of traces is considered important to maintain for legibility.
4112        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4113            @Override
4114            public synchronized void onEvent(int event, String path) { notify(); }
4115        };
4116
4117        try {
4118            observer.startWatching();
4119
4120            // First collect all of the stacks of the most important pids.
4121            if (firstPids != null) {
4122                try {
4123                    int num = firstPids.size();
4124                    for (int i = 0; i < num; i++) {
4125                        synchronized (observer) {
4126                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4127                            observer.wait(200);  // Wait for write-close, give up after 200msec
4128                        }
4129                    }
4130                } catch (InterruptedException e) {
4131                    Log.wtf(TAG, e);
4132                }
4133            }
4134
4135            // Next collect the stacks of the native pids
4136            if (nativeProcs != null) {
4137                int[] pids = Process.getPidsForCommands(nativeProcs);
4138                if (pids != null) {
4139                    for (int pid : pids) {
4140                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4141                    }
4142                }
4143            }
4144
4145            // Lastly, measure CPU usage.
4146            if (processCpuTracker != null) {
4147                processCpuTracker.init();
4148                System.gc();
4149                processCpuTracker.update();
4150                try {
4151                    synchronized (processCpuTracker) {
4152                        processCpuTracker.wait(500); // measure over 1/2 second.
4153                    }
4154                } catch (InterruptedException e) {
4155                }
4156                processCpuTracker.update();
4157
4158                // We'll take the stack crawls of just the top apps using CPU.
4159                final int N = processCpuTracker.countWorkingStats();
4160                int numProcs = 0;
4161                for (int i=0; i<N && numProcs<5; i++) {
4162                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4163                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4164                        numProcs++;
4165                        try {
4166                            synchronized (observer) {
4167                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4168                                observer.wait(200);  // Wait for write-close, give up after 200msec
4169                            }
4170                        } catch (InterruptedException e) {
4171                            Log.wtf(TAG, e);
4172                        }
4173
4174                    }
4175                }
4176            }
4177        } finally {
4178            observer.stopWatching();
4179        }
4180    }
4181
4182    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4183        if (true || IS_USER_BUILD) {
4184            return;
4185        }
4186        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4187        if (tracesPath == null || tracesPath.length() == 0) {
4188            return;
4189        }
4190
4191        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4192        StrictMode.allowThreadDiskWrites();
4193        try {
4194            final File tracesFile = new File(tracesPath);
4195            final File tracesDir = tracesFile.getParentFile();
4196            final File tracesTmp = new File(tracesDir, "__tmp__");
4197            try {
4198                if (!tracesDir.exists()) {
4199                    tracesFile.mkdirs();
4200                    if (!SELinux.restorecon(tracesDir.getPath())) {
4201                        return;
4202                    }
4203                }
4204                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4205
4206                if (tracesFile.exists()) {
4207                    tracesTmp.delete();
4208                    tracesFile.renameTo(tracesTmp);
4209                }
4210                StringBuilder sb = new StringBuilder();
4211                Time tobj = new Time();
4212                tobj.set(System.currentTimeMillis());
4213                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4214                sb.append(": ");
4215                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4216                sb.append(" since ");
4217                sb.append(msg);
4218                FileOutputStream fos = new FileOutputStream(tracesFile);
4219                fos.write(sb.toString().getBytes());
4220                if (app == null) {
4221                    fos.write("\n*** No application process!".getBytes());
4222                }
4223                fos.close();
4224                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4225            } catch (IOException e) {
4226                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4227                return;
4228            }
4229
4230            if (app != null) {
4231                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4232                firstPids.add(app.pid);
4233                dumpStackTraces(tracesPath, firstPids, null, null, null);
4234            }
4235
4236            File lastTracesFile = null;
4237            File curTracesFile = null;
4238            for (int i=9; i>=0; i--) {
4239                String name = String.format(Locale.US, "slow%02d.txt", i);
4240                curTracesFile = new File(tracesDir, name);
4241                if (curTracesFile.exists()) {
4242                    if (lastTracesFile != null) {
4243                        curTracesFile.renameTo(lastTracesFile);
4244                    } else {
4245                        curTracesFile.delete();
4246                    }
4247                }
4248                lastTracesFile = curTracesFile;
4249            }
4250            tracesFile.renameTo(curTracesFile);
4251            if (tracesTmp.exists()) {
4252                tracesTmp.renameTo(tracesFile);
4253            }
4254        } finally {
4255            StrictMode.setThreadPolicy(oldPolicy);
4256        }
4257    }
4258
4259    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4260            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4261        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4262        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4263
4264        if (mController != null) {
4265            try {
4266                // 0 == continue, -1 = kill process immediately
4267                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4268                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4269            } catch (RemoteException e) {
4270                mController = null;
4271                Watchdog.getInstance().setActivityController(null);
4272            }
4273        }
4274
4275        long anrTime = SystemClock.uptimeMillis();
4276        if (MONITOR_CPU_USAGE) {
4277            updateCpuStatsNow();
4278        }
4279
4280        synchronized (this) {
4281            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4282            if (mShuttingDown) {
4283                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4284                return;
4285            } else if (app.notResponding) {
4286                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4287                return;
4288            } else if (app.crashing) {
4289                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4290                return;
4291            }
4292
4293            // In case we come through here for the same app before completing
4294            // this one, mark as anring now so we will bail out.
4295            app.notResponding = true;
4296
4297            // Log the ANR to the event log.
4298            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4299                    app.processName, app.info.flags, annotation);
4300
4301            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4302            firstPids.add(app.pid);
4303
4304            int parentPid = app.pid;
4305            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4306            if (parentPid != app.pid) firstPids.add(parentPid);
4307
4308            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4309
4310            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4311                ProcessRecord r = mLruProcesses.get(i);
4312                if (r != null && r.thread != null) {
4313                    int pid = r.pid;
4314                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4315                        if (r.persistent) {
4316                            firstPids.add(pid);
4317                        } else {
4318                            lastPids.put(pid, Boolean.TRUE);
4319                        }
4320                    }
4321                }
4322            }
4323        }
4324
4325        // Log the ANR to the main log.
4326        StringBuilder info = new StringBuilder();
4327        info.setLength(0);
4328        info.append("ANR in ").append(app.processName);
4329        if (activity != null && activity.shortComponentName != null) {
4330            info.append(" (").append(activity.shortComponentName).append(")");
4331        }
4332        info.append("\n");
4333        info.append("PID: ").append(app.pid).append("\n");
4334        if (annotation != null) {
4335            info.append("Reason: ").append(annotation).append("\n");
4336        }
4337        if (parent != null && parent != activity) {
4338            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4339        }
4340
4341        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4342
4343        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4344                NATIVE_STACKS_OF_INTEREST);
4345
4346        String cpuInfo = null;
4347        if (MONITOR_CPU_USAGE) {
4348            updateCpuStatsNow();
4349            synchronized (mProcessCpuThread) {
4350                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4351            }
4352            info.append(processCpuTracker.printCurrentLoad());
4353            info.append(cpuInfo);
4354        }
4355
4356        info.append(processCpuTracker.printCurrentState(anrTime));
4357
4358        Slog.e(TAG, info.toString());
4359        if (tracesFile == null) {
4360            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4361            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4362        }
4363
4364        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4365                cpuInfo, tracesFile, null);
4366
4367        if (mController != null) {
4368            try {
4369                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4370                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4371                if (res != 0) {
4372                    if (res < 0 && app.pid != MY_PID) {
4373                        Process.killProcess(app.pid);
4374                    } else {
4375                        synchronized (this) {
4376                            mServices.scheduleServiceTimeoutLocked(app);
4377                        }
4378                    }
4379                    return;
4380                }
4381            } catch (RemoteException e) {
4382                mController = null;
4383                Watchdog.getInstance().setActivityController(null);
4384            }
4385        }
4386
4387        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4388        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4389                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4390
4391        synchronized (this) {
4392            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4393                killUnneededProcessLocked(app, "background ANR");
4394                return;
4395            }
4396
4397            // Set the app's notResponding state, and look up the errorReportReceiver
4398            makeAppNotRespondingLocked(app,
4399                    activity != null ? activity.shortComponentName : null,
4400                    annotation != null ? "ANR " + annotation : "ANR",
4401                    info.toString());
4402
4403            // Bring up the infamous App Not Responding dialog
4404            Message msg = Message.obtain();
4405            HashMap<String, Object> map = new HashMap<String, Object>();
4406            msg.what = SHOW_NOT_RESPONDING_MSG;
4407            msg.obj = map;
4408            msg.arg1 = aboveSystem ? 1 : 0;
4409            map.put("app", app);
4410            if (activity != null) {
4411                map.put("activity", activity);
4412            }
4413
4414            mHandler.sendMessage(msg);
4415        }
4416    }
4417
4418    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4419        if (!mLaunchWarningShown) {
4420            mLaunchWarningShown = true;
4421            mHandler.post(new Runnable() {
4422                @Override
4423                public void run() {
4424                    synchronized (ActivityManagerService.this) {
4425                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4426                        d.show();
4427                        mHandler.postDelayed(new Runnable() {
4428                            @Override
4429                            public void run() {
4430                                synchronized (ActivityManagerService.this) {
4431                                    d.dismiss();
4432                                    mLaunchWarningShown = false;
4433                                }
4434                            }
4435                        }, 4000);
4436                    }
4437                }
4438            });
4439        }
4440    }
4441
4442    @Override
4443    public boolean clearApplicationUserData(final String packageName,
4444            final IPackageDataObserver observer, int userId) {
4445        enforceNotIsolatedCaller("clearApplicationUserData");
4446        int uid = Binder.getCallingUid();
4447        int pid = Binder.getCallingPid();
4448        userId = handleIncomingUser(pid, uid,
4449                userId, false, true, "clearApplicationUserData", null);
4450        long callingId = Binder.clearCallingIdentity();
4451        try {
4452            IPackageManager pm = AppGlobals.getPackageManager();
4453            int pkgUid = -1;
4454            synchronized(this) {
4455                try {
4456                    pkgUid = pm.getPackageUid(packageName, userId);
4457                } catch (RemoteException e) {
4458                }
4459                if (pkgUid == -1) {
4460                    Slog.w(TAG, "Invalid packageName: " + packageName);
4461                    if (observer != null) {
4462                        try {
4463                            observer.onRemoveCompleted(packageName, false);
4464                        } catch (RemoteException e) {
4465                            Slog.i(TAG, "Observer no longer exists.");
4466                        }
4467                    }
4468                    return false;
4469                }
4470                if (uid == pkgUid || checkComponentPermission(
4471                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4472                        pid, uid, -1, true)
4473                        == PackageManager.PERMISSION_GRANTED) {
4474                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4475                } else {
4476                    throw new SecurityException("PID " + pid + " does not have permission "
4477                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4478                                    + " of package " + packageName);
4479                }
4480            }
4481
4482            try {
4483                // Clear application user data
4484                pm.clearApplicationUserData(packageName, observer, userId);
4485
4486                // Remove all permissions granted from/to this package
4487                removeUriPermissionsForPackageLocked(packageName, userId, true);
4488
4489                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4490                        Uri.fromParts("package", packageName, null));
4491                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4492                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4493                        null, null, 0, null, null, null, false, false, userId);
4494            } catch (RemoteException e) {
4495            }
4496        } finally {
4497            Binder.restoreCallingIdentity(callingId);
4498        }
4499        return true;
4500    }
4501
4502    @Override
4503    public void killBackgroundProcesses(final String packageName, int userId) {
4504        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4505                != PackageManager.PERMISSION_GRANTED &&
4506                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4507                        != PackageManager.PERMISSION_GRANTED) {
4508            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4509                    + Binder.getCallingPid()
4510                    + ", uid=" + Binder.getCallingUid()
4511                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4512            Slog.w(TAG, msg);
4513            throw new SecurityException(msg);
4514        }
4515
4516        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4517                userId, true, true, "killBackgroundProcesses", null);
4518        long callingId = Binder.clearCallingIdentity();
4519        try {
4520            IPackageManager pm = AppGlobals.getPackageManager();
4521            synchronized(this) {
4522                int appId = -1;
4523                try {
4524                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4525                } catch (RemoteException e) {
4526                }
4527                if (appId == -1) {
4528                    Slog.w(TAG, "Invalid packageName: " + packageName);
4529                    return;
4530                }
4531                killPackageProcessesLocked(packageName, appId, userId,
4532                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4533            }
4534        } finally {
4535            Binder.restoreCallingIdentity(callingId);
4536        }
4537    }
4538
4539    @Override
4540    public void killAllBackgroundProcesses() {
4541        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4542                != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550
4551        long callingId = Binder.clearCallingIdentity();
4552        try {
4553            synchronized(this) {
4554                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4555                final int NP = mProcessNames.getMap().size();
4556                for (int ip=0; ip<NP; ip++) {
4557                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4558                    final int NA = apps.size();
4559                    for (int ia=0; ia<NA; ia++) {
4560                        ProcessRecord app = apps.valueAt(ia);
4561                        if (app.persistent) {
4562                            // we don't kill persistent processes
4563                            continue;
4564                        }
4565                        if (app.removed) {
4566                            procs.add(app);
4567                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4568                            app.removed = true;
4569                            procs.add(app);
4570                        }
4571                    }
4572                }
4573
4574                int N = procs.size();
4575                for (int i=0; i<N; i++) {
4576                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4577                }
4578                mAllowLowerMemLevel = true;
4579                updateOomAdjLocked();
4580                doLowMemReportIfNeededLocked(null);
4581            }
4582        } finally {
4583            Binder.restoreCallingIdentity(callingId);
4584        }
4585    }
4586
4587    @Override
4588    public void forceStopPackage(final String packageName, int userId) {
4589        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4590                != PackageManager.PERMISSION_GRANTED) {
4591            String msg = "Permission Denial: forceStopPackage() from pid="
4592                    + Binder.getCallingPid()
4593                    + ", uid=" + Binder.getCallingUid()
4594                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4595            Slog.w(TAG, msg);
4596            throw new SecurityException(msg);
4597        }
4598        final int callingPid = Binder.getCallingPid();
4599        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4600                userId, true, true, "forceStopPackage", null);
4601        long callingId = Binder.clearCallingIdentity();
4602        try {
4603            IPackageManager pm = AppGlobals.getPackageManager();
4604            synchronized(this) {
4605                int[] users = userId == UserHandle.USER_ALL
4606                        ? getUsersLocked() : new int[] { userId };
4607                for (int user : users) {
4608                    int pkgUid = -1;
4609                    try {
4610                        pkgUid = pm.getPackageUid(packageName, user);
4611                    } catch (RemoteException e) {
4612                    }
4613                    if (pkgUid == -1) {
4614                        Slog.w(TAG, "Invalid packageName: " + packageName);
4615                        continue;
4616                    }
4617                    try {
4618                        pm.setPackageStoppedState(packageName, true, user);
4619                    } catch (RemoteException e) {
4620                    } catch (IllegalArgumentException e) {
4621                        Slog.w(TAG, "Failed trying to unstop package "
4622                                + packageName + ": " + e);
4623                    }
4624                    if (isUserRunningLocked(user, false)) {
4625                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4626                    }
4627                }
4628            }
4629        } finally {
4630            Binder.restoreCallingIdentity(callingId);
4631        }
4632    }
4633
4634    /*
4635     * The pkg name and app id have to be specified.
4636     */
4637    @Override
4638    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4639        if (pkg == null) {
4640            return;
4641        }
4642        // Make sure the uid is valid.
4643        if (appid < 0) {
4644            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4645            return;
4646        }
4647        int callerUid = Binder.getCallingUid();
4648        // Only the system server can kill an application
4649        if (callerUid == Process.SYSTEM_UID) {
4650            // Post an aysnc message to kill the application
4651            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4652            msg.arg1 = appid;
4653            msg.arg2 = 0;
4654            Bundle bundle = new Bundle();
4655            bundle.putString("pkg", pkg);
4656            bundle.putString("reason", reason);
4657            msg.obj = bundle;
4658            mHandler.sendMessage(msg);
4659        } else {
4660            throw new SecurityException(callerUid + " cannot kill pkg: " +
4661                    pkg);
4662        }
4663    }
4664
4665    @Override
4666    public void closeSystemDialogs(String reason) {
4667        enforceNotIsolatedCaller("closeSystemDialogs");
4668
4669        final int pid = Binder.getCallingPid();
4670        final int uid = Binder.getCallingUid();
4671        final long origId = Binder.clearCallingIdentity();
4672        try {
4673            synchronized (this) {
4674                // Only allow this from foreground processes, so that background
4675                // applications can't abuse it to prevent system UI from being shown.
4676                if (uid >= Process.FIRST_APPLICATION_UID) {
4677                    ProcessRecord proc;
4678                    synchronized (mPidsSelfLocked) {
4679                        proc = mPidsSelfLocked.get(pid);
4680                    }
4681                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4682                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4683                                + " from background process " + proc);
4684                        return;
4685                    }
4686                }
4687                closeSystemDialogsLocked(reason);
4688            }
4689        } finally {
4690            Binder.restoreCallingIdentity(origId);
4691        }
4692    }
4693
4694    void closeSystemDialogsLocked(String reason) {
4695        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4696        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4697                | Intent.FLAG_RECEIVER_FOREGROUND);
4698        if (reason != null) {
4699            intent.putExtra("reason", reason);
4700        }
4701        mWindowManager.closeSystemDialogs(reason);
4702
4703        mStackSupervisor.closeSystemDialogsLocked();
4704
4705        broadcastIntentLocked(null, null, intent, null,
4706                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4707                Process.SYSTEM_UID, UserHandle.USER_ALL);
4708    }
4709
4710    @Override
4711    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4712        enforceNotIsolatedCaller("getProcessMemoryInfo");
4713        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4714        for (int i=pids.length-1; i>=0; i--) {
4715            ProcessRecord proc;
4716            int oomAdj;
4717            synchronized (this) {
4718                synchronized (mPidsSelfLocked) {
4719                    proc = mPidsSelfLocked.get(pids[i]);
4720                    oomAdj = proc != null ? proc.setAdj : 0;
4721                }
4722            }
4723            infos[i] = new Debug.MemoryInfo();
4724            Debug.getMemoryInfo(pids[i], infos[i]);
4725            if (proc != null) {
4726                synchronized (this) {
4727                    if (proc.thread != null && proc.setAdj == oomAdj) {
4728                        // Record this for posterity if the process has been stable.
4729                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4730                                infos[i].getTotalUss(), false, proc.pkgList);
4731                    }
4732                }
4733            }
4734        }
4735        return infos;
4736    }
4737
4738    @Override
4739    public long[] getProcessPss(int[] pids) {
4740        enforceNotIsolatedCaller("getProcessPss");
4741        long[] pss = new long[pids.length];
4742        for (int i=pids.length-1; i>=0; i--) {
4743            ProcessRecord proc;
4744            int oomAdj;
4745            synchronized (this) {
4746                synchronized (mPidsSelfLocked) {
4747                    proc = mPidsSelfLocked.get(pids[i]);
4748                    oomAdj = proc != null ? proc.setAdj : 0;
4749                }
4750            }
4751            long[] tmpUss = new long[1];
4752            pss[i] = Debug.getPss(pids[i], tmpUss);
4753            if (proc != null) {
4754                synchronized (this) {
4755                    if (proc.thread != null && proc.setAdj == oomAdj) {
4756                        // Record this for posterity if the process has been stable.
4757                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4758                    }
4759                }
4760            }
4761        }
4762        return pss;
4763    }
4764
4765    @Override
4766    public void killApplicationProcess(String processName, int uid) {
4767        if (processName == null) {
4768            return;
4769        }
4770
4771        int callerUid = Binder.getCallingUid();
4772        // Only the system server can kill an application
4773        if (callerUid == Process.SYSTEM_UID) {
4774            synchronized (this) {
4775                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4776                if (app != null && app.thread != null) {
4777                    try {
4778                        app.thread.scheduleSuicide();
4779                    } catch (RemoteException e) {
4780                        // If the other end already died, then our work here is done.
4781                    }
4782                } else {
4783                    Slog.w(TAG, "Process/uid not found attempting kill of "
4784                            + processName + " / " + uid);
4785                }
4786            }
4787        } else {
4788            throw new SecurityException(callerUid + " cannot kill app process: " +
4789                    processName);
4790        }
4791    }
4792
4793    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4794        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4795                false, true, false, false, UserHandle.getUserId(uid), reason);
4796        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4797                Uri.fromParts("package", packageName, null));
4798        if (!mProcessesReady) {
4799            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4800                    | Intent.FLAG_RECEIVER_FOREGROUND);
4801        }
4802        intent.putExtra(Intent.EXTRA_UID, uid);
4803        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4804        broadcastIntentLocked(null, null, intent,
4805                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4806                false, false,
4807                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4808    }
4809
4810    private void forceStopUserLocked(int userId, String reason) {
4811        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4812        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4813        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4814                | Intent.FLAG_RECEIVER_FOREGROUND);
4815        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4816        broadcastIntentLocked(null, null, intent,
4817                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4818                false, false,
4819                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4820    }
4821
4822    private final boolean killPackageProcessesLocked(String packageName, int appId,
4823            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4824            boolean doit, boolean evenPersistent, String reason) {
4825        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4826
4827        // Remove all processes this package may have touched: all with the
4828        // same UID (except for the system or root user), and all whose name
4829        // matches the package name.
4830        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4831        final int NP = mProcessNames.getMap().size();
4832        for (int ip=0; ip<NP; ip++) {
4833            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4834            final int NA = apps.size();
4835            for (int ia=0; ia<NA; ia++) {
4836                ProcessRecord app = apps.valueAt(ia);
4837                if (app.persistent && !evenPersistent) {
4838                    // we don't kill persistent processes
4839                    continue;
4840                }
4841                if (app.removed) {
4842                    if (doit) {
4843                        procs.add(app);
4844                    }
4845                    continue;
4846                }
4847
4848                // Skip process if it doesn't meet our oom adj requirement.
4849                if (app.setAdj < minOomAdj) {
4850                    continue;
4851                }
4852
4853                // If no package is specified, we call all processes under the
4854                // give user id.
4855                if (packageName == null) {
4856                    if (app.userId != userId) {
4857                        continue;
4858                    }
4859                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4860                        continue;
4861                    }
4862                // Package has been specified, we want to hit all processes
4863                // that match it.  We need to qualify this by the processes
4864                // that are running under the specified app and user ID.
4865                } else {
4866                    if (UserHandle.getAppId(app.uid) != appId) {
4867                        continue;
4868                    }
4869                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4870                        continue;
4871                    }
4872                    if (!app.pkgList.containsKey(packageName)) {
4873                        continue;
4874                    }
4875                }
4876
4877                // Process has passed all conditions, kill it!
4878                if (!doit) {
4879                    return true;
4880                }
4881                app.removed = true;
4882                procs.add(app);
4883            }
4884        }
4885
4886        int N = procs.size();
4887        for (int i=0; i<N; i++) {
4888            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4889        }
4890        updateOomAdjLocked();
4891        return N > 0;
4892    }
4893
4894    private final boolean forceStopPackageLocked(String name, int appId,
4895            boolean callerWillRestart, boolean purgeCache, boolean doit,
4896            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4897        int i;
4898        int N;
4899
4900        if (userId == UserHandle.USER_ALL && name == null) {
4901            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4902        }
4903
4904        if (appId < 0 && name != null) {
4905            try {
4906                appId = UserHandle.getAppId(
4907                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4908            } catch (RemoteException e) {
4909            }
4910        }
4911
4912        if (doit) {
4913            if (name != null) {
4914                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4915                        + " user=" + userId + ": " + reason);
4916            } else {
4917                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4918            }
4919
4920            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4921            for (int ip=pmap.size()-1; ip>=0; ip--) {
4922                SparseArray<Long> ba = pmap.valueAt(ip);
4923                for (i=ba.size()-1; i>=0; i--) {
4924                    boolean remove = false;
4925                    final int entUid = ba.keyAt(i);
4926                    if (name != null) {
4927                        if (userId == UserHandle.USER_ALL) {
4928                            if (UserHandle.getAppId(entUid) == appId) {
4929                                remove = true;
4930                            }
4931                        } else {
4932                            if (entUid == UserHandle.getUid(userId, appId)) {
4933                                remove = true;
4934                            }
4935                        }
4936                    } else if (UserHandle.getUserId(entUid) == userId) {
4937                        remove = true;
4938                    }
4939                    if (remove) {
4940                        ba.removeAt(i);
4941                    }
4942                }
4943                if (ba.size() == 0) {
4944                    pmap.removeAt(ip);
4945                }
4946            }
4947        }
4948
4949        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4950                -100, callerWillRestart, true, doit, evenPersistent,
4951                name == null ? ("stop user " + userId) : ("stop " + name));
4952
4953        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4954            if (!doit) {
4955                return true;
4956            }
4957            didSomething = true;
4958        }
4959
4960        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4961            if (!doit) {
4962                return true;
4963            }
4964            didSomething = true;
4965        }
4966
4967        if (name == null) {
4968            // Remove all sticky broadcasts from this user.
4969            mStickyBroadcasts.remove(userId);
4970        }
4971
4972        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4973        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4974                userId, providers)) {
4975            if (!doit) {
4976                return true;
4977            }
4978            didSomething = true;
4979        }
4980        N = providers.size();
4981        for (i=0; i<N; i++) {
4982            removeDyingProviderLocked(null, providers.get(i), true);
4983        }
4984
4985        // Remove transient permissions granted from/to this package/user
4986        removeUriPermissionsForPackageLocked(name, userId, false);
4987
4988        if (name == null || uninstalling) {
4989            // Remove pending intents.  For now we only do this when force
4990            // stopping users, because we have some problems when doing this
4991            // for packages -- app widgets are not currently cleaned up for
4992            // such packages, so they can be left with bad pending intents.
4993            if (mIntentSenderRecords.size() > 0) {
4994                Iterator<WeakReference<PendingIntentRecord>> it
4995                        = mIntentSenderRecords.values().iterator();
4996                while (it.hasNext()) {
4997                    WeakReference<PendingIntentRecord> wpir = it.next();
4998                    if (wpir == null) {
4999                        it.remove();
5000                        continue;
5001                    }
5002                    PendingIntentRecord pir = wpir.get();
5003                    if (pir == null) {
5004                        it.remove();
5005                        continue;
5006                    }
5007                    if (name == null) {
5008                        // Stopping user, remove all objects for the user.
5009                        if (pir.key.userId != userId) {
5010                            // Not the same user, skip it.
5011                            continue;
5012                        }
5013                    } else {
5014                        if (UserHandle.getAppId(pir.uid) != appId) {
5015                            // Different app id, skip it.
5016                            continue;
5017                        }
5018                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5019                            // Different user, skip it.
5020                            continue;
5021                        }
5022                        if (!pir.key.packageName.equals(name)) {
5023                            // Different package, skip it.
5024                            continue;
5025                        }
5026                    }
5027                    if (!doit) {
5028                        return true;
5029                    }
5030                    didSomething = true;
5031                    it.remove();
5032                    pir.canceled = true;
5033                    if (pir.key.activity != null) {
5034                        pir.key.activity.pendingResults.remove(pir.ref);
5035                    }
5036                }
5037            }
5038        }
5039
5040        if (doit) {
5041            if (purgeCache && name != null) {
5042                AttributeCache ac = AttributeCache.instance();
5043                if (ac != null) {
5044                    ac.removePackage(name);
5045                }
5046            }
5047            if (mBooted) {
5048                mStackSupervisor.resumeTopActivitiesLocked();
5049                mStackSupervisor.scheduleIdleLocked();
5050            }
5051        }
5052
5053        return didSomething;
5054    }
5055
5056    private final boolean removeProcessLocked(ProcessRecord app,
5057            boolean callerWillRestart, boolean allowRestart, String reason) {
5058        final String name = app.processName;
5059        final int uid = app.uid;
5060        if (DEBUG_PROCESSES) Slog.d(
5061            TAG, "Force removing proc " + app.toShortString() + " (" + name
5062            + "/" + uid + ")");
5063
5064        mProcessNames.remove(name, uid);
5065        mIsolatedProcesses.remove(app.uid);
5066        if (mHeavyWeightProcess == app) {
5067            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5068                    mHeavyWeightProcess.userId, 0));
5069            mHeavyWeightProcess = null;
5070        }
5071        boolean needRestart = false;
5072        if (app.pid > 0 && app.pid != MY_PID) {
5073            int pid = app.pid;
5074            synchronized (mPidsSelfLocked) {
5075                mPidsSelfLocked.remove(pid);
5076                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5077            }
5078            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5079                    app.processName, app.info.uid);
5080            if (app.isolated) {
5081                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5082            }
5083            killUnneededProcessLocked(app, reason);
5084            handleAppDiedLocked(app, true, allowRestart);
5085            removeLruProcessLocked(app);
5086
5087            if (app.persistent && !app.isolated) {
5088                if (!callerWillRestart) {
5089                    addAppLocked(app.info, false, null /* ABI override */);
5090                } else {
5091                    needRestart = true;
5092                }
5093            }
5094        } else {
5095            mRemovedProcesses.add(app);
5096        }
5097
5098        return needRestart;
5099    }
5100
5101    private final void processStartTimedOutLocked(ProcessRecord app) {
5102        final int pid = app.pid;
5103        boolean gone = false;
5104        synchronized (mPidsSelfLocked) {
5105            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5106            if (knownApp != null && knownApp.thread == null) {
5107                mPidsSelfLocked.remove(pid);
5108                gone = true;
5109            }
5110        }
5111
5112        if (gone) {
5113            Slog.w(TAG, "Process " + app + " failed to attach");
5114            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5115                    pid, app.uid, app.processName);
5116            mProcessNames.remove(app.processName, app.uid);
5117            mIsolatedProcesses.remove(app.uid);
5118            if (mHeavyWeightProcess == app) {
5119                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5120                        mHeavyWeightProcess.userId, 0));
5121                mHeavyWeightProcess = null;
5122            }
5123            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5124                    app.processName, app.info.uid);
5125            if (app.isolated) {
5126                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5127            }
5128            // Take care of any launching providers waiting for this process.
5129            checkAppInLaunchingProvidersLocked(app, true);
5130            // Take care of any services that are waiting for the process.
5131            mServices.processStartTimedOutLocked(app);
5132            killUnneededProcessLocked(app, "start timeout");
5133            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5134                Slog.w(TAG, "Unattached app died before backup, skipping");
5135                try {
5136                    IBackupManager bm = IBackupManager.Stub.asInterface(
5137                            ServiceManager.getService(Context.BACKUP_SERVICE));
5138                    bm.agentDisconnected(app.info.packageName);
5139                } catch (RemoteException e) {
5140                    // Can't happen; the backup manager is local
5141                }
5142            }
5143            if (isPendingBroadcastProcessLocked(pid)) {
5144                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5145                skipPendingBroadcastLocked(pid);
5146            }
5147        } else {
5148            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5149        }
5150    }
5151
5152    private final boolean attachApplicationLocked(IApplicationThread thread,
5153            int pid) {
5154
5155        // Find the application record that is being attached...  either via
5156        // the pid if we are running in multiple processes, or just pull the
5157        // next app record if we are emulating process with anonymous threads.
5158        ProcessRecord app;
5159        if (pid != MY_PID && pid >= 0) {
5160            synchronized (mPidsSelfLocked) {
5161                app = mPidsSelfLocked.get(pid);
5162            }
5163        } else {
5164            app = null;
5165        }
5166
5167        if (app == null) {
5168            Slog.w(TAG, "No pending application record for pid " + pid
5169                    + " (IApplicationThread " + thread + "); dropping process");
5170            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5171            if (pid > 0 && pid != MY_PID) {
5172                Process.killProcessQuiet(pid);
5173            } else {
5174                try {
5175                    thread.scheduleExit();
5176                } catch (Exception e) {
5177                    // Ignore exceptions.
5178                }
5179            }
5180            return false;
5181        }
5182
5183        // If this application record is still attached to a previous
5184        // process, clean it up now.
5185        if (app.thread != null) {
5186            handleAppDiedLocked(app, true, true);
5187        }
5188
5189        // Tell the process all about itself.
5190
5191        if (localLOGV) Slog.v(
5192                TAG, "Binding process pid " + pid + " to record " + app);
5193
5194        final String processName = app.processName;
5195        try {
5196            AppDeathRecipient adr = new AppDeathRecipient(
5197                    app, pid, thread);
5198            thread.asBinder().linkToDeath(adr, 0);
5199            app.deathRecipient = adr;
5200        } catch (RemoteException e) {
5201            app.resetPackageList(mProcessStats);
5202            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5203            return false;
5204        }
5205
5206        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5207
5208        app.makeActive(thread, mProcessStats);
5209        app.curAdj = app.setAdj = -100;
5210        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5211        app.forcingToForeground = null;
5212        updateProcessForegroundLocked(app, false, false);
5213        app.hasShownUi = false;
5214        app.debugging = false;
5215        app.cached = false;
5216
5217        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5218
5219        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5220        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5221
5222        if (!normalMode) {
5223            Slog.i(TAG, "Launching preboot mode app: " + app);
5224        }
5225
5226        if (localLOGV) Slog.v(
5227            TAG, "New app record " + app
5228            + " thread=" + thread.asBinder() + " pid=" + pid);
5229        try {
5230            int testMode = IApplicationThread.DEBUG_OFF;
5231            if (mDebugApp != null && mDebugApp.equals(processName)) {
5232                testMode = mWaitForDebugger
5233                    ? IApplicationThread.DEBUG_WAIT
5234                    : IApplicationThread.DEBUG_ON;
5235                app.debugging = true;
5236                if (mDebugTransient) {
5237                    mDebugApp = mOrigDebugApp;
5238                    mWaitForDebugger = mOrigWaitForDebugger;
5239                }
5240            }
5241            String profileFile = app.instrumentationProfileFile;
5242            ParcelFileDescriptor profileFd = null;
5243            boolean profileAutoStop = false;
5244            if (mProfileApp != null && mProfileApp.equals(processName)) {
5245                mProfileProc = app;
5246                profileFile = mProfileFile;
5247                profileFd = mProfileFd;
5248                profileAutoStop = mAutoStopProfiler;
5249            }
5250            boolean enableOpenGlTrace = false;
5251            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5252                enableOpenGlTrace = true;
5253                mOpenGlTraceApp = null;
5254            }
5255
5256            // If the app is being launched for restore or full backup, set it up specially
5257            boolean isRestrictedBackupMode = false;
5258            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5259                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5260                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5261                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5262            }
5263
5264            ensurePackageDexOpt(app.instrumentationInfo != null
5265                    ? app.instrumentationInfo.packageName
5266                    : app.info.packageName);
5267            if (app.instrumentationClass != null) {
5268                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5269            }
5270            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5271                    + processName + " with config " + mConfiguration);
5272            ApplicationInfo appInfo = app.instrumentationInfo != null
5273                    ? app.instrumentationInfo : app.info;
5274            app.compat = compatibilityInfoForPackageLocked(appInfo);
5275            if (profileFd != null) {
5276                profileFd = profileFd.dup();
5277            }
5278            thread.bindApplication(processName, appInfo, providers,
5279                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5280                    app.instrumentationArguments, app.instrumentationWatcher,
5281                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5282                    isRestrictedBackupMode || !normalMode, app.persistent,
5283                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5284                    mCoreSettingsObserver.getCoreSettingsLocked());
5285            updateLruProcessLocked(app, false, null);
5286            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5287        } catch (Exception e) {
5288            // todo: Yikes!  What should we do?  For now we will try to
5289            // start another process, but that could easily get us in
5290            // an infinite loop of restarting processes...
5291            Slog.w(TAG, "Exception thrown during bind!", e);
5292
5293            app.resetPackageList(mProcessStats);
5294            app.unlinkDeathRecipient();
5295            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5296            return false;
5297        }
5298
5299        // Remove this record from the list of starting applications.
5300        mPersistentStartingProcesses.remove(app);
5301        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5302                "Attach application locked removing on hold: " + app);
5303        mProcessesOnHold.remove(app);
5304
5305        boolean badApp = false;
5306        boolean didSomething = false;
5307
5308        // See if the top visible activity is waiting to run in this process...
5309        if (normalMode) {
5310            try {
5311                if (mStackSupervisor.attachApplicationLocked(app)) {
5312                    didSomething = true;
5313                }
5314            } catch (Exception e) {
5315                badApp = true;
5316            }
5317        }
5318
5319        // Find any services that should be running in this process...
5320        if (!badApp) {
5321            try {
5322                didSomething |= mServices.attachApplicationLocked(app, processName);
5323            } catch (Exception e) {
5324                badApp = true;
5325            }
5326        }
5327
5328        // Check if a next-broadcast receiver is in this process...
5329        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5330            try {
5331                didSomething |= sendPendingBroadcastsLocked(app);
5332            } catch (Exception e) {
5333                // If the app died trying to launch the receiver we declare it 'bad'
5334                badApp = true;
5335            }
5336        }
5337
5338        // Check whether the next backup agent is in this process...
5339        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5340            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5341            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5342            try {
5343                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5344                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5345                        mBackupTarget.backupMode);
5346            } catch (Exception e) {
5347                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5348                e.printStackTrace();
5349            }
5350        }
5351
5352        if (badApp) {
5353            // todo: Also need to kill application to deal with all
5354            // kinds of exceptions.
5355            handleAppDiedLocked(app, false, true);
5356            return false;
5357        }
5358
5359        if (!didSomething) {
5360            updateOomAdjLocked();
5361        }
5362
5363        return true;
5364    }
5365
5366    @Override
5367    public final void attachApplication(IApplicationThread thread) {
5368        synchronized (this) {
5369            int callingPid = Binder.getCallingPid();
5370            final long origId = Binder.clearCallingIdentity();
5371            attachApplicationLocked(thread, callingPid);
5372            Binder.restoreCallingIdentity(origId);
5373        }
5374    }
5375
5376    @Override
5377    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5378        final long origId = Binder.clearCallingIdentity();
5379        synchronized (this) {
5380            ActivityStack stack = ActivityRecord.getStackLocked(token);
5381            if (stack != null) {
5382                ActivityRecord r =
5383                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5384                if (stopProfiling) {
5385                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5386                        try {
5387                            mProfileFd.close();
5388                        } catch (IOException e) {
5389                        }
5390                        clearProfilerLocked();
5391                    }
5392                }
5393            }
5394        }
5395        Binder.restoreCallingIdentity(origId);
5396    }
5397
5398    void enableScreenAfterBoot() {
5399        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5400                SystemClock.uptimeMillis());
5401        mWindowManager.enableScreenAfterBoot();
5402
5403        synchronized (this) {
5404            updateEventDispatchingLocked();
5405        }
5406    }
5407
5408    @Override
5409    public void showBootMessage(final CharSequence msg, final boolean always) {
5410        enforceNotIsolatedCaller("showBootMessage");
5411        mWindowManager.showBootMessage(msg, always);
5412    }
5413
5414    @Override
5415    public void dismissKeyguardOnNextActivity() {
5416        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5417        final long token = Binder.clearCallingIdentity();
5418        try {
5419            synchronized (this) {
5420                if (DEBUG_LOCKSCREEN) logLockScreen("");
5421                if (mLockScreenShown) {
5422                    mLockScreenShown = false;
5423                    comeOutOfSleepIfNeededLocked();
5424                }
5425                mStackSupervisor.setDismissKeyguard(true);
5426            }
5427        } finally {
5428            Binder.restoreCallingIdentity(token);
5429        }
5430    }
5431
5432    final void finishBooting() {
5433        // Register receivers to handle package update events
5434        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5435
5436        synchronized (this) {
5437            // Ensure that any processes we had put on hold are now started
5438            // up.
5439            final int NP = mProcessesOnHold.size();
5440            if (NP > 0) {
5441                ArrayList<ProcessRecord> procs =
5442                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5443                for (int ip=0; ip<NP; ip++) {
5444                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5445                            + procs.get(ip));
5446                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5447                }
5448            }
5449
5450            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5451                // Start looking for apps that are abusing wake locks.
5452                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5453                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5454                // Tell anyone interested that we are done booting!
5455                SystemProperties.set("sys.boot_completed", "1");
5456                SystemProperties.set("dev.bootcomplete", "1");
5457                for (int i=0; i<mStartedUsers.size(); i++) {
5458                    UserStartedState uss = mStartedUsers.valueAt(i);
5459                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5460                        uss.mState = UserStartedState.STATE_RUNNING;
5461                        final int userId = mStartedUsers.keyAt(i);
5462                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5463                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5464                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5465                        broadcastIntentLocked(null, null, intent, null,
5466                                new IIntentReceiver.Stub() {
5467                                    @Override
5468                                    public void performReceive(Intent intent, int resultCode,
5469                                            String data, Bundle extras, boolean ordered,
5470                                            boolean sticky, int sendingUser) {
5471                                        synchronized (ActivityManagerService.this) {
5472                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5473                                                    true, false);
5474                                        }
5475                                    }
5476                                },
5477                                0, null, null,
5478                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5479                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5480                                userId);
5481                    }
5482                }
5483                scheduleStartProfilesLocked();
5484            }
5485        }
5486    }
5487
5488    final void ensureBootCompleted() {
5489        boolean booting;
5490        boolean enableScreen;
5491        synchronized (this) {
5492            booting = mBooting;
5493            mBooting = false;
5494            enableScreen = !mBooted;
5495            mBooted = true;
5496        }
5497
5498        if (booting) {
5499            finishBooting();
5500        }
5501
5502        if (enableScreen) {
5503            enableScreenAfterBoot();
5504        }
5505    }
5506
5507    @Override
5508    public final void activityResumed(IBinder token) {
5509        final long origId = Binder.clearCallingIdentity();
5510        synchronized(this) {
5511            ActivityStack stack = ActivityRecord.getStackLocked(token);
5512            if (stack != null) {
5513                ActivityRecord.activityResumedLocked(token);
5514            }
5515        }
5516        Binder.restoreCallingIdentity(origId);
5517    }
5518
5519    @Override
5520    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5521        final long origId = Binder.clearCallingIdentity();
5522        synchronized(this) {
5523            ActivityStack stack = ActivityRecord.getStackLocked(token);
5524            if (stack != null) {
5525                stack.activityPausedLocked(token, false, persistentState);
5526            }
5527        }
5528        Binder.restoreCallingIdentity(origId);
5529    }
5530
5531    @Override
5532    public final void activityStopped(IBinder token, Bundle icicle,
5533            PersistableBundle persistentState, CharSequence description) {
5534        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5535
5536        // Refuse possible leaked file descriptors
5537        if (icicle != null && icicle.hasFileDescriptors()) {
5538            throw new IllegalArgumentException("File descriptors passed in Bundle");
5539        }
5540
5541        final long origId = Binder.clearCallingIdentity();
5542
5543        synchronized (this) {
5544            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5545            if (r != null) {
5546                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5547            }
5548        }
5549
5550        trimApplications();
5551
5552        Binder.restoreCallingIdentity(origId);
5553    }
5554
5555    @Override
5556    public final void activityDestroyed(IBinder token) {
5557        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5558        synchronized (this) {
5559            ActivityStack stack = ActivityRecord.getStackLocked(token);
5560            if (stack != null) {
5561                stack.activityDestroyedLocked(token);
5562            }
5563        }
5564    }
5565
5566    @Override
5567    public String getCallingPackage(IBinder token) {
5568        synchronized (this) {
5569            ActivityRecord r = getCallingRecordLocked(token);
5570            return r != null ? r.info.packageName : null;
5571        }
5572    }
5573
5574    @Override
5575    public ComponentName getCallingActivity(IBinder token) {
5576        synchronized (this) {
5577            ActivityRecord r = getCallingRecordLocked(token);
5578            return r != null ? r.intent.getComponent() : null;
5579        }
5580    }
5581
5582    private ActivityRecord getCallingRecordLocked(IBinder token) {
5583        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5584        if (r == null) {
5585            return null;
5586        }
5587        return r.resultTo;
5588    }
5589
5590    @Override
5591    public ComponentName getActivityClassForToken(IBinder token) {
5592        synchronized(this) {
5593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5594            if (r == null) {
5595                return null;
5596            }
5597            return r.intent.getComponent();
5598        }
5599    }
5600
5601    @Override
5602    public String getPackageForToken(IBinder token) {
5603        synchronized(this) {
5604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5605            if (r == null) {
5606                return null;
5607            }
5608            return r.packageName;
5609        }
5610    }
5611
5612    @Override
5613    public IIntentSender getIntentSender(int type,
5614            String packageName, IBinder token, String resultWho,
5615            int requestCode, Intent[] intents, String[] resolvedTypes,
5616            int flags, Bundle options, int userId) {
5617        enforceNotIsolatedCaller("getIntentSender");
5618        // Refuse possible leaked file descriptors
5619        if (intents != null) {
5620            if (intents.length < 1) {
5621                throw new IllegalArgumentException("Intents array length must be >= 1");
5622            }
5623            for (int i=0; i<intents.length; i++) {
5624                Intent intent = intents[i];
5625                if (intent != null) {
5626                    if (intent.hasFileDescriptors()) {
5627                        throw new IllegalArgumentException("File descriptors passed in Intent");
5628                    }
5629                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5630                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5631                        throw new IllegalArgumentException(
5632                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5633                    }
5634                    intents[i] = new Intent(intent);
5635                }
5636            }
5637            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5638                throw new IllegalArgumentException(
5639                        "Intent array length does not match resolvedTypes length");
5640            }
5641        }
5642        if (options != null) {
5643            if (options.hasFileDescriptors()) {
5644                throw new IllegalArgumentException("File descriptors passed in options");
5645            }
5646        }
5647
5648        synchronized(this) {
5649            int callingUid = Binder.getCallingUid();
5650            int origUserId = userId;
5651            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5652                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5653                    "getIntentSender", null);
5654            if (origUserId == UserHandle.USER_CURRENT) {
5655                // We don't want to evaluate this until the pending intent is
5656                // actually executed.  However, we do want to always do the
5657                // security checking for it above.
5658                userId = UserHandle.USER_CURRENT;
5659            }
5660            try {
5661                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5662                    int uid = AppGlobals.getPackageManager()
5663                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5664                    if (!UserHandle.isSameApp(callingUid, uid)) {
5665                        String msg = "Permission Denial: getIntentSender() from pid="
5666                            + Binder.getCallingPid()
5667                            + ", uid=" + Binder.getCallingUid()
5668                            + ", (need uid=" + uid + ")"
5669                            + " is not allowed to send as package " + packageName;
5670                        Slog.w(TAG, msg);
5671                        throw new SecurityException(msg);
5672                    }
5673                }
5674
5675                return getIntentSenderLocked(type, packageName, callingUid, userId,
5676                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5677
5678            } catch (RemoteException e) {
5679                throw new SecurityException(e);
5680            }
5681        }
5682    }
5683
5684    IIntentSender getIntentSenderLocked(int type, String packageName,
5685            int callingUid, int userId, IBinder token, String resultWho,
5686            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5687            Bundle options) {
5688        if (DEBUG_MU)
5689            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5690        ActivityRecord activity = null;
5691        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5692            activity = ActivityRecord.isInStackLocked(token);
5693            if (activity == null) {
5694                return null;
5695            }
5696            if (activity.finishing) {
5697                return null;
5698            }
5699        }
5700
5701        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5702        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5703        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5704        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5705                |PendingIntent.FLAG_UPDATE_CURRENT);
5706
5707        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5708                type, packageName, activity, resultWho,
5709                requestCode, intents, resolvedTypes, flags, options, userId);
5710        WeakReference<PendingIntentRecord> ref;
5711        ref = mIntentSenderRecords.get(key);
5712        PendingIntentRecord rec = ref != null ? ref.get() : null;
5713        if (rec != null) {
5714            if (!cancelCurrent) {
5715                if (updateCurrent) {
5716                    if (rec.key.requestIntent != null) {
5717                        rec.key.requestIntent.replaceExtras(intents != null ?
5718                                intents[intents.length - 1] : null);
5719                    }
5720                    if (intents != null) {
5721                        intents[intents.length-1] = rec.key.requestIntent;
5722                        rec.key.allIntents = intents;
5723                        rec.key.allResolvedTypes = resolvedTypes;
5724                    } else {
5725                        rec.key.allIntents = null;
5726                        rec.key.allResolvedTypes = null;
5727                    }
5728                }
5729                return rec;
5730            }
5731            rec.canceled = true;
5732            mIntentSenderRecords.remove(key);
5733        }
5734        if (noCreate) {
5735            return rec;
5736        }
5737        rec = new PendingIntentRecord(this, key, callingUid);
5738        mIntentSenderRecords.put(key, rec.ref);
5739        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5740            if (activity.pendingResults == null) {
5741                activity.pendingResults
5742                        = new HashSet<WeakReference<PendingIntentRecord>>();
5743            }
5744            activity.pendingResults.add(rec.ref);
5745        }
5746        return rec;
5747    }
5748
5749    @Override
5750    public void cancelIntentSender(IIntentSender sender) {
5751        if (!(sender instanceof PendingIntentRecord)) {
5752            return;
5753        }
5754        synchronized(this) {
5755            PendingIntentRecord rec = (PendingIntentRecord)sender;
5756            try {
5757                int uid = AppGlobals.getPackageManager()
5758                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5759                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5760                    String msg = "Permission Denial: cancelIntentSender() from pid="
5761                        + Binder.getCallingPid()
5762                        + ", uid=" + Binder.getCallingUid()
5763                        + " is not allowed to cancel packges "
5764                        + rec.key.packageName;
5765                    Slog.w(TAG, msg);
5766                    throw new SecurityException(msg);
5767                }
5768            } catch (RemoteException e) {
5769                throw new SecurityException(e);
5770            }
5771            cancelIntentSenderLocked(rec, true);
5772        }
5773    }
5774
5775    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5776        rec.canceled = true;
5777        mIntentSenderRecords.remove(rec.key);
5778        if (cleanActivity && rec.key.activity != null) {
5779            rec.key.activity.pendingResults.remove(rec.ref);
5780        }
5781    }
5782
5783    @Override
5784    public String getPackageForIntentSender(IIntentSender pendingResult) {
5785        if (!(pendingResult instanceof PendingIntentRecord)) {
5786            return null;
5787        }
5788        try {
5789            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5790            return res.key.packageName;
5791        } catch (ClassCastException e) {
5792        }
5793        return null;
5794    }
5795
5796    @Override
5797    public int getUidForIntentSender(IIntentSender sender) {
5798        if (sender instanceof PendingIntentRecord) {
5799            try {
5800                PendingIntentRecord res = (PendingIntentRecord)sender;
5801                return res.uid;
5802            } catch (ClassCastException e) {
5803            }
5804        }
5805        return -1;
5806    }
5807
5808    @Override
5809    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5810        if (!(pendingResult instanceof PendingIntentRecord)) {
5811            return false;
5812        }
5813        try {
5814            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5815            if (res.key.allIntents == null) {
5816                return false;
5817            }
5818            for (int i=0; i<res.key.allIntents.length; i++) {
5819                Intent intent = res.key.allIntents[i];
5820                if (intent.getPackage() != null && intent.getComponent() != null) {
5821                    return false;
5822                }
5823            }
5824            return true;
5825        } catch (ClassCastException e) {
5826        }
5827        return false;
5828    }
5829
5830    @Override
5831    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5832        if (!(pendingResult instanceof PendingIntentRecord)) {
5833            return false;
5834        }
5835        try {
5836            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5837            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5838                return true;
5839            }
5840            return false;
5841        } catch (ClassCastException e) {
5842        }
5843        return false;
5844    }
5845
5846    @Override
5847    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5848        if (!(pendingResult instanceof PendingIntentRecord)) {
5849            return null;
5850        }
5851        try {
5852            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5853            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5854        } catch (ClassCastException e) {
5855        }
5856        return null;
5857    }
5858
5859    @Override
5860    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5861        if (!(pendingResult instanceof PendingIntentRecord)) {
5862            return null;
5863        }
5864        try {
5865            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5866            Intent intent = res.key.requestIntent;
5867            if (intent != null) {
5868                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5869                        || res.lastTagPrefix.equals(prefix))) {
5870                    return res.lastTag;
5871                }
5872                res.lastTagPrefix = prefix;
5873                StringBuilder sb = new StringBuilder(128);
5874                if (prefix != null) {
5875                    sb.append(prefix);
5876                }
5877                if (intent.getAction() != null) {
5878                    sb.append(intent.getAction());
5879                } else if (intent.getComponent() != null) {
5880                    intent.getComponent().appendShortString(sb);
5881                } else {
5882                    sb.append("?");
5883                }
5884                return res.lastTag = sb.toString();
5885            }
5886        } catch (ClassCastException e) {
5887        }
5888        return null;
5889    }
5890
5891    @Override
5892    public void setProcessLimit(int max) {
5893        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5894                "setProcessLimit()");
5895        synchronized (this) {
5896            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5897            mProcessLimitOverride = max;
5898        }
5899        trimApplications();
5900    }
5901
5902    @Override
5903    public int getProcessLimit() {
5904        synchronized (this) {
5905            return mProcessLimitOverride;
5906        }
5907    }
5908
5909    void foregroundTokenDied(ForegroundToken token) {
5910        synchronized (ActivityManagerService.this) {
5911            synchronized (mPidsSelfLocked) {
5912                ForegroundToken cur
5913                    = mForegroundProcesses.get(token.pid);
5914                if (cur != token) {
5915                    return;
5916                }
5917                mForegroundProcesses.remove(token.pid);
5918                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5919                if (pr == null) {
5920                    return;
5921                }
5922                pr.forcingToForeground = null;
5923                updateProcessForegroundLocked(pr, false, false);
5924            }
5925            updateOomAdjLocked();
5926        }
5927    }
5928
5929    @Override
5930    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5931        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5932                "setProcessForeground()");
5933        synchronized(this) {
5934            boolean changed = false;
5935
5936            synchronized (mPidsSelfLocked) {
5937                ProcessRecord pr = mPidsSelfLocked.get(pid);
5938                if (pr == null && isForeground) {
5939                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5940                    return;
5941                }
5942                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5943                if (oldToken != null) {
5944                    oldToken.token.unlinkToDeath(oldToken, 0);
5945                    mForegroundProcesses.remove(pid);
5946                    if (pr != null) {
5947                        pr.forcingToForeground = null;
5948                    }
5949                    changed = true;
5950                }
5951                if (isForeground && token != null) {
5952                    ForegroundToken newToken = new ForegroundToken() {
5953                        @Override
5954                        public void binderDied() {
5955                            foregroundTokenDied(this);
5956                        }
5957                    };
5958                    newToken.pid = pid;
5959                    newToken.token = token;
5960                    try {
5961                        token.linkToDeath(newToken, 0);
5962                        mForegroundProcesses.put(pid, newToken);
5963                        pr.forcingToForeground = token;
5964                        changed = true;
5965                    } catch (RemoteException e) {
5966                        // If the process died while doing this, we will later
5967                        // do the cleanup with the process death link.
5968                    }
5969                }
5970            }
5971
5972            if (changed) {
5973                updateOomAdjLocked();
5974            }
5975        }
5976    }
5977
5978    // =========================================================
5979    // PERMISSIONS
5980    // =========================================================
5981
5982    static class PermissionController extends IPermissionController.Stub {
5983        ActivityManagerService mActivityManagerService;
5984        PermissionController(ActivityManagerService activityManagerService) {
5985            mActivityManagerService = activityManagerService;
5986        }
5987
5988        @Override
5989        public boolean checkPermission(String permission, int pid, int uid) {
5990            return mActivityManagerService.checkPermission(permission, pid,
5991                    uid) == PackageManager.PERMISSION_GRANTED;
5992        }
5993    }
5994
5995    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5996        @Override
5997        public int checkComponentPermission(String permission, int pid, int uid,
5998                int owningUid, boolean exported) {
5999            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6000                    owningUid, exported);
6001        }
6002
6003        @Override
6004        public Object getAMSLock() {
6005            return ActivityManagerService.this;
6006        }
6007    }
6008
6009    /**
6010     * This can be called with or without the global lock held.
6011     */
6012    int checkComponentPermission(String permission, int pid, int uid,
6013            int owningUid, boolean exported) {
6014        // We might be performing an operation on behalf of an indirect binder
6015        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6016        // client identity accordingly before proceeding.
6017        Identity tlsIdentity = sCallerIdentity.get();
6018        if (tlsIdentity != null) {
6019            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6020                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6021            uid = tlsIdentity.uid;
6022            pid = tlsIdentity.pid;
6023        }
6024
6025        if (pid == MY_PID) {
6026            return PackageManager.PERMISSION_GRANTED;
6027        }
6028
6029        return ActivityManager.checkComponentPermission(permission, uid,
6030                owningUid, exported);
6031    }
6032
6033    /**
6034     * As the only public entry point for permissions checking, this method
6035     * can enforce the semantic that requesting a check on a null global
6036     * permission is automatically denied.  (Internally a null permission
6037     * string is used when calling {@link #checkComponentPermission} in cases
6038     * when only uid-based security is needed.)
6039     *
6040     * This can be called with or without the global lock held.
6041     */
6042    @Override
6043    public int checkPermission(String permission, int pid, int uid) {
6044        if (permission == null) {
6045            return PackageManager.PERMISSION_DENIED;
6046        }
6047        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6048    }
6049
6050    /**
6051     * Binder IPC calls go through the public entry point.
6052     * This can be called with or without the global lock held.
6053     */
6054    int checkCallingPermission(String permission) {
6055        return checkPermission(permission,
6056                Binder.getCallingPid(),
6057                UserHandle.getAppId(Binder.getCallingUid()));
6058    }
6059
6060    /**
6061     * This can be called with or without the global lock held.
6062     */
6063    void enforceCallingPermission(String permission, String func) {
6064        if (checkCallingPermission(permission)
6065                == PackageManager.PERMISSION_GRANTED) {
6066            return;
6067        }
6068
6069        String msg = "Permission Denial: " + func + " from pid="
6070                + Binder.getCallingPid()
6071                + ", uid=" + Binder.getCallingUid()
6072                + " requires " + permission;
6073        Slog.w(TAG, msg);
6074        throw new SecurityException(msg);
6075    }
6076
6077    /**
6078     * Determine if UID is holding permissions required to access {@link Uri} in
6079     * the given {@link ProviderInfo}. Final permission checking is always done
6080     * in {@link ContentProvider}.
6081     */
6082    private final boolean checkHoldingPermissionsLocked(
6083            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6084        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6085                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6086        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6087            return false;
6088        }
6089
6090        if (pi.applicationInfo.uid == uid) {
6091            return true;
6092        } else if (!pi.exported) {
6093            return false;
6094        }
6095
6096        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6097        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6098        try {
6099            // check if target holds top-level <provider> permissions
6100            if (!readMet && pi.readPermission != null
6101                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6102                readMet = true;
6103            }
6104            if (!writeMet && pi.writePermission != null
6105                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6106                writeMet = true;
6107            }
6108
6109            // track if unprotected read/write is allowed; any denied
6110            // <path-permission> below removes this ability
6111            boolean allowDefaultRead = pi.readPermission == null;
6112            boolean allowDefaultWrite = pi.writePermission == null;
6113
6114            // check if target holds any <path-permission> that match uri
6115            final PathPermission[] pps = pi.pathPermissions;
6116            if (pps != null) {
6117                final String path = grantUri.uri.getPath();
6118                int i = pps.length;
6119                while (i > 0 && (!readMet || !writeMet)) {
6120                    i--;
6121                    PathPermission pp = pps[i];
6122                    if (pp.match(path)) {
6123                        if (!readMet) {
6124                            final String pprperm = pp.getReadPermission();
6125                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6126                                    + pprperm + " for " + pp.getPath()
6127                                    + ": match=" + pp.match(path)
6128                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6129                            if (pprperm != null) {
6130                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6131                                    readMet = true;
6132                                } else {
6133                                    allowDefaultRead = false;
6134                                }
6135                            }
6136                        }
6137                        if (!writeMet) {
6138                            final String ppwperm = pp.getWritePermission();
6139                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6140                                    + ppwperm + " for " + pp.getPath()
6141                                    + ": match=" + pp.match(path)
6142                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6143                            if (ppwperm != null) {
6144                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6145                                    writeMet = true;
6146                                } else {
6147                                    allowDefaultWrite = false;
6148                                }
6149                            }
6150                        }
6151                    }
6152                }
6153            }
6154
6155            // grant unprotected <provider> read/write, if not blocked by
6156            // <path-permission> above
6157            if (allowDefaultRead) readMet = true;
6158            if (allowDefaultWrite) writeMet = true;
6159
6160        } catch (RemoteException e) {
6161            return false;
6162        }
6163
6164        return readMet && writeMet;
6165    }
6166
6167    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6168        ProviderInfo pi = null;
6169        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6170        if (cpr != null) {
6171            pi = cpr.info;
6172        } else {
6173            try {
6174                pi = AppGlobals.getPackageManager().resolveContentProvider(
6175                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6176            } catch (RemoteException ex) {
6177            }
6178        }
6179        return pi;
6180    }
6181
6182    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6183        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6184        if (targetUris != null) {
6185            return targetUris.get(grantUri);
6186        }
6187        return null;
6188    }
6189
6190    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6191            String targetPkg, int targetUid, GrantUri grantUri) {
6192        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6193        if (targetUris == null) {
6194            targetUris = Maps.newArrayMap();
6195            mGrantedUriPermissions.put(targetUid, targetUris);
6196        }
6197
6198        UriPermission perm = targetUris.get(grantUri);
6199        if (perm == null) {
6200            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6201            targetUris.put(grantUri, perm);
6202        }
6203
6204        return perm;
6205    }
6206
6207    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6208            final int modeFlags) {
6209        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6210        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6211                : UriPermission.STRENGTH_OWNED;
6212
6213        // Root gets to do everything.
6214        if (uid == 0) {
6215            return true;
6216        }
6217
6218        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6219        if (perms == null) return false;
6220
6221        // First look for exact match
6222        final UriPermission exactPerm = perms.get(grantUri);
6223        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6224            return true;
6225        }
6226
6227        // No exact match, look for prefixes
6228        final int N = perms.size();
6229        for (int i = 0; i < N; i++) {
6230            final UriPermission perm = perms.valueAt(i);
6231            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6232                    && perm.getStrength(modeFlags) >= minStrength) {
6233                return true;
6234            }
6235        }
6236
6237        return false;
6238    }
6239
6240    @Override
6241    public int checkUriPermission(Uri uri, int pid, int uid,
6242            final int modeFlags, int userId) {
6243        enforceNotIsolatedCaller("checkUriPermission");
6244
6245        // Another redirected-binder-call permissions check as in
6246        // {@link checkComponentPermission}.
6247        Identity tlsIdentity = sCallerIdentity.get();
6248        if (tlsIdentity != null) {
6249            uid = tlsIdentity.uid;
6250            pid = tlsIdentity.pid;
6251        }
6252
6253        // Our own process gets to do everything.
6254        if (pid == MY_PID) {
6255            return PackageManager.PERMISSION_GRANTED;
6256        }
6257        synchronized (this) {
6258            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6259                    ? PackageManager.PERMISSION_GRANTED
6260                    : PackageManager.PERMISSION_DENIED;
6261        }
6262    }
6263
6264    /**
6265     * Check if the targetPkg can be granted permission to access uri by
6266     * the callingUid using the given modeFlags.  Throws a security exception
6267     * if callingUid is not allowed to do this.  Returns the uid of the target
6268     * if the URI permission grant should be performed; returns -1 if it is not
6269     * needed (for example targetPkg already has permission to access the URI).
6270     * If you already know the uid of the target, you can supply it in
6271     * lastTargetUid else set that to -1.
6272     */
6273    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6274            final int modeFlags, int lastTargetUid) {
6275        if (!Intent.isAccessUriMode(modeFlags)) {
6276            return -1;
6277        }
6278
6279        if (targetPkg != null) {
6280            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6281                    "Checking grant " + targetPkg + " permission to " + grantUri);
6282        }
6283
6284        final IPackageManager pm = AppGlobals.getPackageManager();
6285
6286        // If this is not a content: uri, we can't do anything with it.
6287        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6288            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6289                    "Can't grant URI permission for non-content URI: " + grantUri);
6290            return -1;
6291        }
6292
6293        final String authority = grantUri.uri.getAuthority();
6294        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6295        if (pi == null) {
6296            Slog.w(TAG, "No content provider found for permission check: " +
6297                    grantUri.uri.toSafeString());
6298            return -1;
6299        }
6300
6301        int targetUid = lastTargetUid;
6302        if (targetUid < 0 && targetPkg != null) {
6303            try {
6304                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6305                if (targetUid < 0) {
6306                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6307                            "Can't grant URI permission no uid for: " + targetPkg);
6308                    return -1;
6309                }
6310            } catch (RemoteException ex) {
6311                return -1;
6312            }
6313        }
6314
6315        if (targetUid >= 0) {
6316            // First...  does the target actually need this permission?
6317            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6318                // No need to grant the target this permission.
6319                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6320                        "Target " + targetPkg + " already has full permission to " + grantUri);
6321                return -1;
6322            }
6323        } else {
6324            // First...  there is no target package, so can anyone access it?
6325            boolean allowed = pi.exported;
6326            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6327                if (pi.readPermission != null) {
6328                    allowed = false;
6329                }
6330            }
6331            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6332                if (pi.writePermission != null) {
6333                    allowed = false;
6334                }
6335            }
6336            if (allowed) {
6337                return -1;
6338            }
6339        }
6340
6341        // Second...  is the provider allowing granting of URI permissions?
6342        if (!pi.grantUriPermissions) {
6343            throw new SecurityException("Provider " + pi.packageName
6344                    + "/" + pi.name
6345                    + " does not allow granting of Uri permissions (uri "
6346                    + grantUri + ")");
6347        }
6348        if (pi.uriPermissionPatterns != null) {
6349            final int N = pi.uriPermissionPatterns.length;
6350            boolean allowed = false;
6351            for (int i=0; i<N; i++) {
6352                if (pi.uriPermissionPatterns[i] != null
6353                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6354                    allowed = true;
6355                    break;
6356                }
6357            }
6358            if (!allowed) {
6359                throw new SecurityException("Provider " + pi.packageName
6360                        + "/" + pi.name
6361                        + " does not allow granting of permission to path of Uri "
6362                        + grantUri);
6363            }
6364        }
6365
6366        // Third...  does the caller itself have permission to access
6367        // this uri?
6368        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6369            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6370                // Require they hold a strong enough Uri permission
6371                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6372                    throw new SecurityException("Uid " + callingUid
6373                            + " does not have permission to uri " + grantUri);
6374                }
6375            }
6376        }
6377        return targetUid;
6378    }
6379
6380    @Override
6381    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6382            final int modeFlags, int userId) {
6383        enforceNotIsolatedCaller("checkGrantUriPermission");
6384        synchronized(this) {
6385            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6386                    new GrantUri(userId, uri, false), modeFlags, -1);
6387        }
6388    }
6389
6390    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6391            final int modeFlags, UriPermissionOwner owner) {
6392        if (!Intent.isAccessUriMode(modeFlags)) {
6393            return;
6394        }
6395
6396        // So here we are: the caller has the assumed permission
6397        // to the uri, and the target doesn't.  Let's now give this to
6398        // the target.
6399
6400        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6401                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6402
6403        final String authority = grantUri.uri.getAuthority();
6404        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6405        if (pi == null) {
6406            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6407            return;
6408        }
6409
6410        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6411            grantUri.prefix = true;
6412        }
6413        final UriPermission perm = findOrCreateUriPermissionLocked(
6414                pi.packageName, targetPkg, targetUid, grantUri);
6415        perm.grantModes(modeFlags, owner);
6416    }
6417
6418    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6419            final int modeFlags, UriPermissionOwner owner) {
6420        if (targetPkg == null) {
6421            throw new NullPointerException("targetPkg");
6422        }
6423
6424        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6425                -1);
6426        if (targetUid < 0) {
6427            return;
6428        }
6429
6430        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6431                owner);
6432    }
6433
6434    static class NeededUriGrants extends ArrayList<GrantUri> {
6435        final String targetPkg;
6436        final int targetUid;
6437        final int flags;
6438
6439        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6440            this.targetPkg = targetPkg;
6441            this.targetUid = targetUid;
6442            this.flags = flags;
6443        }
6444    }
6445
6446    /**
6447     * Like checkGrantUriPermissionLocked, but takes an Intent.
6448     */
6449    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6450            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6451        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6452                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6453                + " clip=" + (intent != null ? intent.getClipData() : null)
6454                + " from " + intent + "; flags=0x"
6455                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6456
6457        if (targetPkg == null) {
6458            throw new NullPointerException("targetPkg");
6459        }
6460
6461        if (intent == null) {
6462            return null;
6463        }
6464        Uri data = intent.getData();
6465        ClipData clip = intent.getClipData();
6466        if (data == null && clip == null) {
6467            return null;
6468        }
6469        final IPackageManager pm = AppGlobals.getPackageManager();
6470        int targetUid;
6471        if (needed != null) {
6472            targetUid = needed.targetUid;
6473        } else {
6474            try {
6475                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6476            } catch (RemoteException ex) {
6477                return null;
6478            }
6479            if (targetUid < 0) {
6480                if (DEBUG_URI_PERMISSION) {
6481                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6482                            + " on user " + targetUserId);
6483                }
6484                return null;
6485            }
6486        }
6487        if (data != null) {
6488            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6489            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6490                    targetUid);
6491            if (targetUid > 0) {
6492                if (needed == null) {
6493                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6494                }
6495                needed.add(grantUri);
6496            }
6497        }
6498        if (clip != null) {
6499            for (int i=0; i<clip.getItemCount(); i++) {
6500                Uri uri = clip.getItemAt(i).getUri();
6501                if (uri != null) {
6502                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6503                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6504                            targetUid);
6505                    if (targetUid > 0) {
6506                        if (needed == null) {
6507                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6508                        }
6509                        needed.add(grantUri);
6510                    }
6511                } else {
6512                    Intent clipIntent = clip.getItemAt(i).getIntent();
6513                    if (clipIntent != null) {
6514                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6515                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6516                        if (newNeeded != null) {
6517                            needed = newNeeded;
6518                        }
6519                    }
6520                }
6521            }
6522        }
6523
6524        return needed;
6525    }
6526
6527    /**
6528     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6529     */
6530    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6531            UriPermissionOwner owner) {
6532        if (needed != null) {
6533            for (int i=0; i<needed.size(); i++) {
6534                GrantUri grantUri = needed.get(i);
6535                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6536                        grantUri, needed.flags, owner);
6537            }
6538        }
6539    }
6540
6541    void grantUriPermissionFromIntentLocked(int callingUid,
6542            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6543        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6544                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6545        if (needed == null) {
6546            return;
6547        }
6548
6549        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6550    }
6551
6552    @Override
6553    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6554            final int modeFlags, int userId) {
6555        enforceNotIsolatedCaller("grantUriPermission");
6556        GrantUri grantUri = new GrantUri(userId, uri, false);
6557        synchronized(this) {
6558            final ProcessRecord r = getRecordForAppLocked(caller);
6559            if (r == null) {
6560                throw new SecurityException("Unable to find app for caller "
6561                        + caller
6562                        + " when granting permission to uri " + grantUri);
6563            }
6564            if (targetPkg == null) {
6565                throw new IllegalArgumentException("null target");
6566            }
6567            if (grantUri == null) {
6568                throw new IllegalArgumentException("null uri");
6569            }
6570
6571            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6572                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6573                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6574                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6575
6576            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6577        }
6578    }
6579
6580    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6581        if (perm.modeFlags == 0) {
6582            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6583                    perm.targetUid);
6584            if (perms != null) {
6585                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6586                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6587
6588                perms.remove(perm.uri);
6589                if (perms.isEmpty()) {
6590                    mGrantedUriPermissions.remove(perm.targetUid);
6591                }
6592            }
6593        }
6594    }
6595
6596    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6597        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6598
6599        final IPackageManager pm = AppGlobals.getPackageManager();
6600        final String authority = grantUri.uri.getAuthority();
6601        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6602        if (pi == null) {
6603            Slog.w(TAG, "No content provider found for permission revoke: "
6604                    + grantUri.toSafeString());
6605            return;
6606        }
6607
6608        // Does the caller have this permission on the URI?
6609        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6610            // Right now, if you are not the original owner of the permission,
6611            // you are not allowed to revoke it.
6612            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6613                throw new SecurityException("Uid " + callingUid
6614                        + " does not have permission to uri " + grantUri);
6615            //}
6616        }
6617
6618        boolean persistChanged = false;
6619
6620        // Go through all of the permissions and remove any that match.
6621        int N = mGrantedUriPermissions.size();
6622        for (int i = 0; i < N; i++) {
6623            final int targetUid = mGrantedUriPermissions.keyAt(i);
6624            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6625
6626            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6627                final UriPermission perm = it.next();
6628                if (perm.uri.sourceUserId == grantUri.sourceUserId
6629                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6630                    if (DEBUG_URI_PERMISSION)
6631                        Slog.v(TAG,
6632                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6633                    persistChanged |= perm.revokeModes(
6634                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6635                    if (perm.modeFlags == 0) {
6636                        it.remove();
6637                    }
6638                }
6639            }
6640
6641            if (perms.isEmpty()) {
6642                mGrantedUriPermissions.remove(targetUid);
6643                N--;
6644                i--;
6645            }
6646        }
6647
6648        if (persistChanged) {
6649            schedulePersistUriGrants();
6650        }
6651    }
6652
6653    @Override
6654    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6655            int userId) {
6656        enforceNotIsolatedCaller("revokeUriPermission");
6657        synchronized(this) {
6658            final ProcessRecord r = getRecordForAppLocked(caller);
6659            if (r == null) {
6660                throw new SecurityException("Unable to find app for caller "
6661                        + caller
6662                        + " when revoking permission to uri " + uri);
6663            }
6664            if (uri == null) {
6665                Slog.w(TAG, "revokeUriPermission: null uri");
6666                return;
6667            }
6668
6669            if (!Intent.isAccessUriMode(modeFlags)) {
6670                return;
6671            }
6672
6673            final IPackageManager pm = AppGlobals.getPackageManager();
6674            final String authority = uri.getAuthority();
6675            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6676            if (pi == null) {
6677                Slog.w(TAG, "No content provider found for permission revoke: "
6678                        + uri.toSafeString());
6679                return;
6680            }
6681
6682            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6683        }
6684    }
6685
6686    /**
6687     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6688     * given package.
6689     *
6690     * @param packageName Package name to match, or {@code null} to apply to all
6691     *            packages.
6692     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6693     *            to all users.
6694     * @param persistable If persistable grants should be removed.
6695     */
6696    private void removeUriPermissionsForPackageLocked(
6697            String packageName, int userHandle, boolean persistable) {
6698        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6699            throw new IllegalArgumentException("Must narrow by either package or user");
6700        }
6701
6702        boolean persistChanged = false;
6703
6704        int N = mGrantedUriPermissions.size();
6705        for (int i = 0; i < N; i++) {
6706            final int targetUid = mGrantedUriPermissions.keyAt(i);
6707            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6708
6709            // Only inspect grants matching user
6710            if (userHandle == UserHandle.USER_ALL
6711                    || userHandle == UserHandle.getUserId(targetUid)) {
6712                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6713                    final UriPermission perm = it.next();
6714
6715                    // Only inspect grants matching package
6716                    if (packageName == null || perm.sourcePkg.equals(packageName)
6717                            || perm.targetPkg.equals(packageName)) {
6718                        persistChanged |= perm.revokeModes(
6719                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6720
6721                        // Only remove when no modes remain; any persisted grants
6722                        // will keep this alive.
6723                        if (perm.modeFlags == 0) {
6724                            it.remove();
6725                        }
6726                    }
6727                }
6728
6729                if (perms.isEmpty()) {
6730                    mGrantedUriPermissions.remove(targetUid);
6731                    N--;
6732                    i--;
6733                }
6734            }
6735        }
6736
6737        if (persistChanged) {
6738            schedulePersistUriGrants();
6739        }
6740    }
6741
6742    @Override
6743    public IBinder newUriPermissionOwner(String name) {
6744        enforceNotIsolatedCaller("newUriPermissionOwner");
6745        synchronized(this) {
6746            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6747            return owner.getExternalTokenLocked();
6748        }
6749    }
6750
6751    @Override
6752    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6753            final int modeFlags, int userId) {
6754        synchronized(this) {
6755            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6756            if (owner == null) {
6757                throw new IllegalArgumentException("Unknown owner: " + token);
6758            }
6759            if (fromUid != Binder.getCallingUid()) {
6760                if (Binder.getCallingUid() != Process.myUid()) {
6761                    // Only system code can grant URI permissions on behalf
6762                    // of other users.
6763                    throw new SecurityException("nice try");
6764                }
6765            }
6766            if (targetPkg == null) {
6767                throw new IllegalArgumentException("null target");
6768            }
6769            if (uri == null) {
6770                throw new IllegalArgumentException("null uri");
6771            }
6772
6773            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6774                    modeFlags, owner);
6775        }
6776    }
6777
6778    @Override
6779    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6780        synchronized(this) {
6781            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6782            if (owner == null) {
6783                throw new IllegalArgumentException("Unknown owner: " + token);
6784            }
6785
6786            if (uri == null) {
6787                owner.removeUriPermissionsLocked(mode);
6788            } else {
6789                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6790            }
6791        }
6792    }
6793
6794    private void schedulePersistUriGrants() {
6795        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6796            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6797                    10 * DateUtils.SECOND_IN_MILLIS);
6798        }
6799    }
6800
6801    private void writeGrantedUriPermissions() {
6802        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6803
6804        // Snapshot permissions so we can persist without lock
6805        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6806        synchronized (this) {
6807            final int size = mGrantedUriPermissions.size();
6808            for (int i = 0; i < size; i++) {
6809                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6810                for (UriPermission perm : perms.values()) {
6811                    if (perm.persistedModeFlags != 0) {
6812                        persist.add(perm.snapshot());
6813                    }
6814                }
6815            }
6816        }
6817
6818        FileOutputStream fos = null;
6819        try {
6820            fos = mGrantFile.startWrite();
6821
6822            XmlSerializer out = new FastXmlSerializer();
6823            out.setOutput(fos, "utf-8");
6824            out.startDocument(null, true);
6825            out.startTag(null, TAG_URI_GRANTS);
6826            for (UriPermission.Snapshot perm : persist) {
6827                out.startTag(null, TAG_URI_GRANT);
6828                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6829                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6830                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6831                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6832                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6833                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6834                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6835                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6836                out.endTag(null, TAG_URI_GRANT);
6837            }
6838            out.endTag(null, TAG_URI_GRANTS);
6839            out.endDocument();
6840
6841            mGrantFile.finishWrite(fos);
6842        } catch (IOException e) {
6843            if (fos != null) {
6844                mGrantFile.failWrite(fos);
6845            }
6846        }
6847    }
6848
6849    private void readGrantedUriPermissionsLocked() {
6850        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6851
6852        final long now = System.currentTimeMillis();
6853
6854        FileInputStream fis = null;
6855        try {
6856            fis = mGrantFile.openRead();
6857            final XmlPullParser in = Xml.newPullParser();
6858            in.setInput(fis, null);
6859
6860            int type;
6861            while ((type = in.next()) != END_DOCUMENT) {
6862                final String tag = in.getName();
6863                if (type == START_TAG) {
6864                    if (TAG_URI_GRANT.equals(tag)) {
6865                        final int sourceUserId;
6866                        final int targetUserId;
6867                        final int userHandle = readIntAttribute(in,
6868                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6869                        if (userHandle != UserHandle.USER_NULL) {
6870                            // For backwards compatibility.
6871                            sourceUserId = userHandle;
6872                            targetUserId = userHandle;
6873                        } else {
6874                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6875                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6876                        }
6877                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6878                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6879                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6880                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6881                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6882                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6883
6884                        // Sanity check that provider still belongs to source package
6885                        final ProviderInfo pi = getProviderInfoLocked(
6886                                uri.getAuthority(), sourceUserId);
6887                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6888                            int targetUid = -1;
6889                            try {
6890                                targetUid = AppGlobals.getPackageManager()
6891                                        .getPackageUid(targetPkg, targetUserId);
6892                            } catch (RemoteException e) {
6893                            }
6894                            if (targetUid != -1) {
6895                                final UriPermission perm = findOrCreateUriPermissionLocked(
6896                                        sourcePkg, targetPkg, targetUid,
6897                                        new GrantUri(sourceUserId, uri, prefix));
6898                                perm.initPersistedModes(modeFlags, createdTime);
6899                            }
6900                        } else {
6901                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6902                                    + " but instead found " + pi);
6903                        }
6904                    }
6905                }
6906            }
6907        } catch (FileNotFoundException e) {
6908            // Missing grants is okay
6909        } catch (IOException e) {
6910            Log.wtf(TAG, "Failed reading Uri grants", e);
6911        } catch (XmlPullParserException e) {
6912            Log.wtf(TAG, "Failed reading Uri grants", e);
6913        } finally {
6914            IoUtils.closeQuietly(fis);
6915        }
6916    }
6917
6918    @Override
6919    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6920        enforceNotIsolatedCaller("takePersistableUriPermission");
6921
6922        Preconditions.checkFlagsArgument(modeFlags,
6923                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6924
6925        synchronized (this) {
6926            final int callingUid = Binder.getCallingUid();
6927            boolean persistChanged = false;
6928            GrantUri grantUri = new GrantUri(userId, uri, false);
6929
6930            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6931                    new GrantUri(userId, uri, false));
6932            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6933                    new GrantUri(userId, uri, true));
6934
6935            final boolean exactValid = (exactPerm != null)
6936                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6937            final boolean prefixValid = (prefixPerm != null)
6938                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6939
6940            if (!(exactValid || prefixValid)) {
6941                throw new SecurityException("No persistable permission grants found for UID "
6942                        + callingUid + " and Uri " + grantUri.toSafeString());
6943            }
6944
6945            if (exactValid) {
6946                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6947            }
6948            if (prefixValid) {
6949                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6950            }
6951
6952            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6953
6954            if (persistChanged) {
6955                schedulePersistUriGrants();
6956            }
6957        }
6958    }
6959
6960    @Override
6961    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6962        enforceNotIsolatedCaller("releasePersistableUriPermission");
6963
6964        Preconditions.checkFlagsArgument(modeFlags,
6965                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6966
6967        synchronized (this) {
6968            final int callingUid = Binder.getCallingUid();
6969            boolean persistChanged = false;
6970
6971            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6972                    new GrantUri(userId, uri, false));
6973            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6974                    new GrantUri(userId, uri, true));
6975            if (exactPerm == null && prefixPerm == null) {
6976                throw new SecurityException("No permission grants found for UID " + callingUid
6977                        + " and Uri " + uri.toSafeString());
6978            }
6979
6980            if (exactPerm != null) {
6981                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6982                removeUriPermissionIfNeededLocked(exactPerm);
6983            }
6984            if (prefixPerm != null) {
6985                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6986                removeUriPermissionIfNeededLocked(prefixPerm);
6987            }
6988
6989            if (persistChanged) {
6990                schedulePersistUriGrants();
6991            }
6992        }
6993    }
6994
6995    /**
6996     * Prune any older {@link UriPermission} for the given UID until outstanding
6997     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6998     *
6999     * @return if any mutations occured that require persisting.
7000     */
7001    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7002        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7003        if (perms == null) return false;
7004        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7005
7006        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7007        for (UriPermission perm : perms.values()) {
7008            if (perm.persistedModeFlags != 0) {
7009                persisted.add(perm);
7010            }
7011        }
7012
7013        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7014        if (trimCount <= 0) return false;
7015
7016        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7017        for (int i = 0; i < trimCount; i++) {
7018            final UriPermission perm = persisted.get(i);
7019
7020            if (DEBUG_URI_PERMISSION) {
7021                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7022            }
7023
7024            perm.releasePersistableModes(~0);
7025            removeUriPermissionIfNeededLocked(perm);
7026        }
7027
7028        return true;
7029    }
7030
7031    @Override
7032    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7033            String packageName, boolean incoming) {
7034        enforceNotIsolatedCaller("getPersistedUriPermissions");
7035        Preconditions.checkNotNull(packageName, "packageName");
7036
7037        final int callingUid = Binder.getCallingUid();
7038        final IPackageManager pm = AppGlobals.getPackageManager();
7039        try {
7040            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7041            if (packageUid != callingUid) {
7042                throw new SecurityException(
7043                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7044            }
7045        } catch (RemoteException e) {
7046            throw new SecurityException("Failed to verify package name ownership");
7047        }
7048
7049        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7050        synchronized (this) {
7051            if (incoming) {
7052                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7053                        callingUid);
7054                if (perms == null) {
7055                    Slog.w(TAG, "No permission grants found for " + packageName);
7056                } else {
7057                    for (UriPermission perm : perms.values()) {
7058                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7059                            result.add(perm.buildPersistedPublicApiObject());
7060                        }
7061                    }
7062                }
7063            } else {
7064                final int size = mGrantedUriPermissions.size();
7065                for (int i = 0; i < size; i++) {
7066                    final ArrayMap<GrantUri, UriPermission> perms =
7067                            mGrantedUriPermissions.valueAt(i);
7068                    for (UriPermission perm : perms.values()) {
7069                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7070                            result.add(perm.buildPersistedPublicApiObject());
7071                        }
7072                    }
7073                }
7074            }
7075        }
7076        return new ParceledListSlice<android.content.UriPermission>(result);
7077    }
7078
7079    @Override
7080    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7081        synchronized (this) {
7082            ProcessRecord app =
7083                who != null ? getRecordForAppLocked(who) : null;
7084            if (app == null) return;
7085
7086            Message msg = Message.obtain();
7087            msg.what = WAIT_FOR_DEBUGGER_MSG;
7088            msg.obj = app;
7089            msg.arg1 = waiting ? 1 : 0;
7090            mHandler.sendMessage(msg);
7091        }
7092    }
7093
7094    @Override
7095    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7096        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7097        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7098        outInfo.availMem = Process.getFreeMemory();
7099        outInfo.totalMem = Process.getTotalMemory();
7100        outInfo.threshold = homeAppMem;
7101        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7102        outInfo.hiddenAppThreshold = cachedAppMem;
7103        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7104                ProcessList.SERVICE_ADJ);
7105        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7106                ProcessList.VISIBLE_APP_ADJ);
7107        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7108                ProcessList.FOREGROUND_APP_ADJ);
7109    }
7110
7111    // =========================================================
7112    // TASK MANAGEMENT
7113    // =========================================================
7114
7115    @Override
7116    public List<IAppTask> getAppTasks() {
7117        int callingUid = Binder.getCallingUid();
7118        long ident = Binder.clearCallingIdentity();
7119        synchronized(this) {
7120            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7121            try {
7122                if (localLOGV) Slog.v(TAG, "getAppTasks");
7123
7124                final int N = mRecentTasks.size();
7125                for (int i = 0; i < N; i++) {
7126                    TaskRecord tr = mRecentTasks.get(i);
7127                    // Skip tasks that are not created by the caller
7128                    if (tr.creatorUid == callingUid) {
7129                        ActivityManager.RecentTaskInfo taskInfo =
7130                                createRecentTaskInfoFromTaskRecord(tr);
7131                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7132                        list.add(taskImpl);
7133                    }
7134                }
7135            } finally {
7136                Binder.restoreCallingIdentity(ident);
7137            }
7138            return list;
7139        }
7140    }
7141
7142    @Override
7143    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7144        final int callingUid = Binder.getCallingUid();
7145        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7146
7147        synchronized(this) {
7148            if (localLOGV) Slog.v(
7149                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7150
7151            final boolean allowed = checkCallingPermission(
7152                    android.Manifest.permission.GET_TASKS)
7153                    == PackageManager.PERMISSION_GRANTED;
7154            if (!allowed) {
7155                Slog.w(TAG, "getTasks: caller " + callingUid
7156                        + " does not hold GET_TASKS; limiting output");
7157            }
7158
7159            // TODO: Improve with MRU list from all ActivityStacks.
7160            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7161        }
7162
7163        return list;
7164    }
7165
7166    TaskRecord getMostRecentTask() {
7167        return mRecentTasks.get(0);
7168    }
7169
7170    /**
7171     * Creates a new RecentTaskInfo from a TaskRecord.
7172     */
7173    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7174        // Update the task description to reflect any changes in the task stack
7175        tr.updateTaskDescription();
7176
7177        // Compose the recent task info
7178        ActivityManager.RecentTaskInfo rti
7179                = new ActivityManager.RecentTaskInfo();
7180        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7181        rti.persistentId = tr.taskId;
7182        rti.baseIntent = new Intent(tr.getBaseIntent());
7183        rti.origActivity = tr.origActivity;
7184        rti.description = tr.lastDescription;
7185        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7186        rti.userId = tr.userId;
7187        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7188        return rti;
7189    }
7190
7191    @Override
7192    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7193            int flags, int userId) {
7194        final int callingUid = Binder.getCallingUid();
7195        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7196                false, true, "getRecentTasks", null);
7197
7198        synchronized (this) {
7199            final boolean allowed = checkCallingPermission(
7200                    android.Manifest.permission.GET_TASKS)
7201                    == PackageManager.PERMISSION_GRANTED;
7202            if (!allowed) {
7203                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7204                        + " does not hold GET_TASKS; limiting output");
7205            }
7206            final boolean detailed = checkCallingPermission(
7207                    android.Manifest.permission.GET_DETAILED_TASKS)
7208                    == PackageManager.PERMISSION_GRANTED;
7209
7210            IPackageManager pm = AppGlobals.getPackageManager();
7211
7212            final int N = mRecentTasks.size();
7213            ArrayList<ActivityManager.RecentTaskInfo> res
7214                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7215                            maxNum < N ? maxNum : N);
7216
7217            final Set<Integer> includedUsers;
7218            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7219                includedUsers = getProfileIdsLocked(userId);
7220            } else {
7221                includedUsers = new HashSet<Integer>();
7222            }
7223            includedUsers.add(Integer.valueOf(userId));
7224            for (int i=0; i<N && maxNum > 0; i++) {
7225                TaskRecord tr = mRecentTasks.get(i);
7226                // Only add calling user or related users recent tasks
7227                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7228
7229                // Return the entry if desired by the caller.  We always return
7230                // the first entry, because callers always expect this to be the
7231                // foreground app.  We may filter others if the caller has
7232                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7233                // we should exclude the entry.
7234
7235                if (i == 0
7236                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7237                        || (tr.intent == null)
7238                        || ((tr.intent.getFlags()
7239                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7240                    if (!allowed) {
7241                        // If the caller doesn't have the GET_TASKS permission, then only
7242                        // allow them to see a small subset of tasks -- their own and home.
7243                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7244                            continue;
7245                        }
7246                    }
7247
7248                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7249                    if (!detailed) {
7250                        rti.baseIntent.replaceExtras((Bundle)null);
7251                    }
7252
7253                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7254                        // Check whether this activity is currently available.
7255                        try {
7256                            if (rti.origActivity != null) {
7257                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7258                                        == null) {
7259                                    continue;
7260                                }
7261                            } else if (rti.baseIntent != null) {
7262                                if (pm.queryIntentActivities(rti.baseIntent,
7263                                        null, 0, userId) == null) {
7264                                    continue;
7265                                }
7266                            }
7267                        } catch (RemoteException e) {
7268                            // Will never happen.
7269                        }
7270                    }
7271
7272                    res.add(rti);
7273                    maxNum--;
7274                }
7275            }
7276            return res;
7277        }
7278    }
7279
7280    private TaskRecord recentTaskForIdLocked(int id) {
7281        final int N = mRecentTasks.size();
7282            for (int i=0; i<N; i++) {
7283                TaskRecord tr = mRecentTasks.get(i);
7284                if (tr.taskId == id) {
7285                    return tr;
7286                }
7287            }
7288            return null;
7289    }
7290
7291    @Override
7292    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7293        synchronized (this) {
7294            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7295                    "getTaskThumbnails()");
7296            TaskRecord tr = recentTaskForIdLocked(id);
7297            if (tr != null) {
7298                return tr.getTaskThumbnailsLocked();
7299            }
7300        }
7301        return null;
7302    }
7303
7304    @Override
7305    public Bitmap getTaskTopThumbnail(int id) {
7306        synchronized (this) {
7307            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7308                    "getTaskTopThumbnail()");
7309            TaskRecord tr = recentTaskForIdLocked(id);
7310            if (tr != null) {
7311                return tr.getTaskTopThumbnailLocked();
7312            }
7313        }
7314        return null;
7315    }
7316
7317    @Override
7318    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7319        synchronized (this) {
7320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7321            if (r != null) {
7322                r.taskDescription = td;
7323                r.task.updateTaskDescription();
7324            }
7325        }
7326    }
7327
7328    @Override
7329    public boolean removeSubTask(int taskId, int subTaskIndex) {
7330        synchronized (this) {
7331            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7332                    "removeSubTask()");
7333            long ident = Binder.clearCallingIdentity();
7334            try {
7335                TaskRecord tr = recentTaskForIdLocked(taskId);
7336                if (tr != null) {
7337                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7338                }
7339                return false;
7340            } finally {
7341                Binder.restoreCallingIdentity(ident);
7342            }
7343        }
7344    }
7345
7346    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7347        if (!pr.killedByAm) {
7348            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7349            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7350                    pr.processName, pr.setAdj, reason);
7351            pr.killedByAm = true;
7352            Process.killProcessQuiet(pr.pid);
7353        }
7354    }
7355
7356    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7357        tr.disposeThumbnail();
7358        mRecentTasks.remove(tr);
7359        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7360        Intent baseIntent = new Intent(
7361                tr.intent != null ? tr.intent : tr.affinityIntent);
7362        ComponentName component = baseIntent.getComponent();
7363        if (component == null) {
7364            Slog.w(TAG, "Now component for base intent of task: " + tr);
7365            return;
7366        }
7367
7368        // Find any running services associated with this app.
7369        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7370
7371        if (killProcesses) {
7372            // Find any running processes associated with this app.
7373            final String pkg = component.getPackageName();
7374            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7375            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7376            for (int i=0; i<pmap.size(); i++) {
7377                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7378                for (int j=0; j<uids.size(); j++) {
7379                    ProcessRecord proc = uids.valueAt(j);
7380                    if (proc.userId != tr.userId) {
7381                        continue;
7382                    }
7383                    if (!proc.pkgList.containsKey(pkg)) {
7384                        continue;
7385                    }
7386                    procs.add(proc);
7387                }
7388            }
7389
7390            // Kill the running processes.
7391            for (int i=0; i<procs.size(); i++) {
7392                ProcessRecord pr = procs.get(i);
7393                if (pr == mHomeProcess) {
7394                    // Don't kill the home process along with tasks from the same package.
7395                    continue;
7396                }
7397                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7398                    killUnneededProcessLocked(pr, "remove task");
7399                } else {
7400                    pr.waitingToKill = "remove task";
7401                }
7402            }
7403        }
7404    }
7405
7406    /**
7407     * Removes the task with the specified task id.
7408     *
7409     * @param taskId Identifier of the task to be removed.
7410     * @param flags Additional operational flags.  May be 0 or
7411     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7412     * @return Returns true if the given task was found and removed.
7413     */
7414    private boolean removeTaskByIdLocked(int taskId, int flags) {
7415        TaskRecord tr = recentTaskForIdLocked(taskId);
7416        if (tr != null) {
7417            tr.removeTaskActivitiesLocked(-1, false);
7418            cleanUpRemovedTaskLocked(tr, flags);
7419            if (tr.isPersistable) {
7420                notifyTaskPersisterLocked(tr, true);
7421            }
7422            return true;
7423        }
7424        return false;
7425    }
7426
7427    @Override
7428    public boolean removeTask(int taskId, int flags) {
7429        synchronized (this) {
7430            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7431                    "removeTask()");
7432            long ident = Binder.clearCallingIdentity();
7433            try {
7434                return removeTaskByIdLocked(taskId, flags);
7435            } finally {
7436                Binder.restoreCallingIdentity(ident);
7437            }
7438        }
7439    }
7440
7441    /**
7442     * TODO: Add mController hook
7443     */
7444    @Override
7445    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7446        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7447                "moveTaskToFront()");
7448
7449        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7450        synchronized(this) {
7451            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7452                    Binder.getCallingUid(), "Task to front")) {
7453                ActivityOptions.abort(options);
7454                return;
7455            }
7456            final long origId = Binder.clearCallingIdentity();
7457            try {
7458                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7459                if (task == null) {
7460                    return;
7461                }
7462                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7463                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7464                    return;
7465                }
7466                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7467            } finally {
7468                Binder.restoreCallingIdentity(origId);
7469            }
7470            ActivityOptions.abort(options);
7471        }
7472    }
7473
7474    @Override
7475    public void moveTaskToBack(int taskId) {
7476        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7477                "moveTaskToBack()");
7478
7479        synchronized(this) {
7480            TaskRecord tr = recentTaskForIdLocked(taskId);
7481            if (tr != null) {
7482                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7483                ActivityStack stack = tr.stack;
7484                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7485                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7486                            Binder.getCallingUid(), "Task to back")) {
7487                        return;
7488                    }
7489                }
7490                final long origId = Binder.clearCallingIdentity();
7491                try {
7492                    stack.moveTaskToBackLocked(taskId, null);
7493                } finally {
7494                    Binder.restoreCallingIdentity(origId);
7495                }
7496            }
7497        }
7498    }
7499
7500    /**
7501     * Moves an activity, and all of the other activities within the same task, to the bottom
7502     * of the history stack.  The activity's order within the task is unchanged.
7503     *
7504     * @param token A reference to the activity we wish to move
7505     * @param nonRoot If false then this only works if the activity is the root
7506     *                of a task; if true it will work for any activity in a task.
7507     * @return Returns true if the move completed, false if not.
7508     */
7509    @Override
7510    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7511        enforceNotIsolatedCaller("moveActivityTaskToBack");
7512        synchronized(this) {
7513            final long origId = Binder.clearCallingIdentity();
7514            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7515            if (taskId >= 0) {
7516                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7517            }
7518            Binder.restoreCallingIdentity(origId);
7519        }
7520        return false;
7521    }
7522
7523    @Override
7524    public void moveTaskBackwards(int task) {
7525        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7526                "moveTaskBackwards()");
7527
7528        synchronized(this) {
7529            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7530                    Binder.getCallingUid(), "Task backwards")) {
7531                return;
7532            }
7533            final long origId = Binder.clearCallingIdentity();
7534            moveTaskBackwardsLocked(task);
7535            Binder.restoreCallingIdentity(origId);
7536        }
7537    }
7538
7539    private final void moveTaskBackwardsLocked(int task) {
7540        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7541    }
7542
7543    @Override
7544    public IBinder getHomeActivityToken() throws RemoteException {
7545        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7546                "getHomeActivityToken()");
7547        synchronized (this) {
7548            return mStackSupervisor.getHomeActivityToken();
7549        }
7550    }
7551
7552    @Override
7553    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7554            IActivityContainerCallback callback) throws RemoteException {
7555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7556                "createActivityContainer()");
7557        synchronized (this) {
7558            if (parentActivityToken == null) {
7559                throw new IllegalArgumentException("parent token must not be null");
7560            }
7561            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7562            if (r == null) {
7563                return null;
7564            }
7565            if (callback == null) {
7566                throw new IllegalArgumentException("callback must not be null");
7567            }
7568            return mStackSupervisor.createActivityContainer(r, callback);
7569        }
7570    }
7571
7572    @Override
7573    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7574        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7575                "deleteActivityContainer()");
7576        synchronized (this) {
7577            mStackSupervisor.deleteActivityContainer(container);
7578        }
7579    }
7580
7581    @Override
7582    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7583            throws RemoteException {
7584        synchronized (this) {
7585            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7586            if (stack != null) {
7587                return stack.mActivityContainer;
7588            }
7589            return null;
7590        }
7591    }
7592
7593    @Override
7594    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7595        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7596                "moveTaskToStack()");
7597        if (stackId == HOME_STACK_ID) {
7598            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7599                    new RuntimeException("here").fillInStackTrace());
7600        }
7601        synchronized (this) {
7602            long ident = Binder.clearCallingIdentity();
7603            try {
7604                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7605                        + stackId + " toTop=" + toTop);
7606                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7607            } finally {
7608                Binder.restoreCallingIdentity(ident);
7609            }
7610        }
7611    }
7612
7613    @Override
7614    public void resizeStack(int stackBoxId, Rect bounds) {
7615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7616                "resizeStackBox()");
7617        long ident = Binder.clearCallingIdentity();
7618        try {
7619            mWindowManager.resizeStack(stackBoxId, bounds);
7620        } finally {
7621            Binder.restoreCallingIdentity(ident);
7622        }
7623    }
7624
7625    @Override
7626    public List<StackInfo> getAllStackInfos() {
7627        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7628                "getAllStackInfos()");
7629        long ident = Binder.clearCallingIdentity();
7630        try {
7631            synchronized (this) {
7632                return mStackSupervisor.getAllStackInfosLocked();
7633            }
7634        } finally {
7635            Binder.restoreCallingIdentity(ident);
7636        }
7637    }
7638
7639    @Override
7640    public StackInfo getStackInfo(int stackId) {
7641        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7642                "getStackInfo()");
7643        long ident = Binder.clearCallingIdentity();
7644        try {
7645            synchronized (this) {
7646                return mStackSupervisor.getStackInfoLocked(stackId);
7647            }
7648        } finally {
7649            Binder.restoreCallingIdentity(ident);
7650        }
7651    }
7652
7653    @Override
7654    public boolean isInHomeStack(int taskId) {
7655        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7656                "getStackInfo()");
7657        long ident = Binder.clearCallingIdentity();
7658        try {
7659            synchronized (this) {
7660                TaskRecord tr = recentTaskForIdLocked(taskId);
7661                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7662            }
7663        } finally {
7664            Binder.restoreCallingIdentity(ident);
7665        }
7666    }
7667
7668    @Override
7669    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7670        synchronized(this) {
7671            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7672        }
7673    }
7674
7675    private boolean isLockTaskAuthorized(ComponentName name) {
7676        final DevicePolicyManager dpm = (DevicePolicyManager)
7677                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7678        return dpm != null && dpm.isLockTaskPermitted(name);
7679    }
7680
7681    private void startLockTaskMode(TaskRecord task) {
7682        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7683            return;
7684        }
7685        long ident = Binder.clearCallingIdentity();
7686        try {
7687            synchronized (this) {
7688                // Since we lost lock on task, make sure it is still there.
7689                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7690                if (task != null) {
7691                    mStackSupervisor.setLockTaskModeLocked(task);
7692                }
7693            }
7694        } finally {
7695            Binder.restoreCallingIdentity(ident);
7696        }
7697    }
7698
7699    @Override
7700    public void startLockTaskMode(int taskId) {
7701        long ident = Binder.clearCallingIdentity();
7702        try {
7703            final TaskRecord task;
7704            synchronized (this) {
7705                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7706            }
7707            if (task != null) {
7708                startLockTaskMode(task);
7709            }
7710        } finally {
7711            Binder.restoreCallingIdentity(ident);
7712        }
7713    }
7714
7715    @Override
7716    public void startLockTaskMode(IBinder token) {
7717        long ident = Binder.clearCallingIdentity();
7718        try {
7719            final TaskRecord task;
7720            synchronized (this) {
7721                final ActivityRecord r = ActivityRecord.forToken(token);
7722                if (r == null) {
7723                    return;
7724                }
7725                task = r.task;
7726            }
7727            if (task != null) {
7728                startLockTaskMode(task);
7729            }
7730        } finally {
7731            Binder.restoreCallingIdentity(ident);
7732        }
7733    }
7734
7735    @Override
7736    public void stopLockTaskMode() {
7737        // Check if the calling task is eligible to use lock task
7738        final int uid = Binder.getCallingUid();
7739        try {
7740            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7741            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7742                return;
7743            }
7744        } catch (RemoteException e) {
7745            Log.d(TAG, "stopLockTaskMode " + e);
7746            return;
7747        }
7748        // Stop lock task
7749        synchronized (this) {
7750            mStackSupervisor.setLockTaskModeLocked(null);
7751        }
7752    }
7753
7754    @Override
7755    public boolean isInLockTaskMode() {
7756        synchronized (this) {
7757            return mStackSupervisor.isInLockTaskMode();
7758        }
7759    }
7760
7761    // =========================================================
7762    // CONTENT PROVIDERS
7763    // =========================================================
7764
7765    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7766        List<ProviderInfo> providers = null;
7767        try {
7768            providers = AppGlobals.getPackageManager().
7769                queryContentProviders(app.processName, app.uid,
7770                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7771        } catch (RemoteException ex) {
7772        }
7773        if (DEBUG_MU)
7774            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7775        int userId = app.userId;
7776        if (providers != null) {
7777            int N = providers.size();
7778            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7779            for (int i=0; i<N; i++) {
7780                ProviderInfo cpi =
7781                    (ProviderInfo)providers.get(i);
7782                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7783                        cpi.name, cpi.flags);
7784                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7785                    // This is a singleton provider, but a user besides the
7786                    // default user is asking to initialize a process it runs
7787                    // in...  well, no, it doesn't actually run in this process,
7788                    // it runs in the process of the default user.  Get rid of it.
7789                    providers.remove(i);
7790                    N--;
7791                    i--;
7792                    continue;
7793                }
7794
7795                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7796                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7797                if (cpr == null) {
7798                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7799                    mProviderMap.putProviderByClass(comp, cpr);
7800                }
7801                if (DEBUG_MU)
7802                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7803                app.pubProviders.put(cpi.name, cpr);
7804                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7805                    // Don't add this if it is a platform component that is marked
7806                    // to run in multiple processes, because this is actually
7807                    // part of the framework so doesn't make sense to track as a
7808                    // separate apk in the process.
7809                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7810                            mProcessStats);
7811                }
7812                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7813            }
7814        }
7815        return providers;
7816    }
7817
7818    /**
7819     * Check if {@link ProcessRecord} has a possible chance at accessing the
7820     * given {@link ProviderInfo}. Final permission checking is always done
7821     * in {@link ContentProvider}.
7822     */
7823    private final String checkContentProviderPermissionLocked(
7824            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7825        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7826        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7827        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7828        // Looking for cross-user grants before to enforce the typical cross-users permissions
7829        if (userId != UserHandle.getUserId(callingUid)) {
7830            if (perms != null) {
7831                for (GrantUri grantUri : perms.keySet()) {
7832                    if (grantUri.sourceUserId == userId) {
7833                        String authority = grantUri.uri.getAuthority();
7834                        if (authority.equals(cpi.authority)) {
7835                            return null;
7836                        }
7837                    }
7838                }
7839            }
7840        }
7841        if (checkUser) {
7842            userId = handleIncomingUser(callingPid, callingUid, userId,
7843                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7844        }
7845        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7846                cpi.applicationInfo.uid, cpi.exported)
7847                == PackageManager.PERMISSION_GRANTED) {
7848            return null;
7849        }
7850        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7851                cpi.applicationInfo.uid, cpi.exported)
7852                == PackageManager.PERMISSION_GRANTED) {
7853            return null;
7854        }
7855
7856        PathPermission[] pps = cpi.pathPermissions;
7857        if (pps != null) {
7858            int i = pps.length;
7859            while (i > 0) {
7860                i--;
7861                PathPermission pp = pps[i];
7862                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7863                        cpi.applicationInfo.uid, cpi.exported)
7864                        == PackageManager.PERMISSION_GRANTED) {
7865                    return null;
7866                }
7867                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7868                        cpi.applicationInfo.uid, cpi.exported)
7869                        == PackageManager.PERMISSION_GRANTED) {
7870                    return null;
7871                }
7872            }
7873        }
7874
7875        if (perms != null) {
7876            for (GrantUri grantUri : perms.keySet()) {
7877                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7878                    return null;
7879                }
7880            }
7881        }
7882
7883        String msg;
7884        if (!cpi.exported) {
7885            msg = "Permission Denial: opening provider " + cpi.name
7886                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7887                    + ", uid=" + callingUid + ") that is not exported from uid "
7888                    + cpi.applicationInfo.uid;
7889        } else {
7890            msg = "Permission Denial: opening provider " + cpi.name
7891                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7892                    + ", uid=" + callingUid + ") requires "
7893                    + cpi.readPermission + " or " + cpi.writePermission;
7894        }
7895        Slog.w(TAG, msg);
7896        return msg;
7897    }
7898
7899    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7900            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7901        if (r != null) {
7902            for (int i=0; i<r.conProviders.size(); i++) {
7903                ContentProviderConnection conn = r.conProviders.get(i);
7904                if (conn.provider == cpr) {
7905                    if (DEBUG_PROVIDER) Slog.v(TAG,
7906                            "Adding provider requested by "
7907                            + r.processName + " from process "
7908                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7909                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7910                    if (stable) {
7911                        conn.stableCount++;
7912                        conn.numStableIncs++;
7913                    } else {
7914                        conn.unstableCount++;
7915                        conn.numUnstableIncs++;
7916                    }
7917                    return conn;
7918                }
7919            }
7920            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7921            if (stable) {
7922                conn.stableCount = 1;
7923                conn.numStableIncs = 1;
7924            } else {
7925                conn.unstableCount = 1;
7926                conn.numUnstableIncs = 1;
7927            }
7928            cpr.connections.add(conn);
7929            r.conProviders.add(conn);
7930            return conn;
7931        }
7932        cpr.addExternalProcessHandleLocked(externalProcessToken);
7933        return null;
7934    }
7935
7936    boolean decProviderCountLocked(ContentProviderConnection conn,
7937            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7938        if (conn != null) {
7939            cpr = conn.provider;
7940            if (DEBUG_PROVIDER) Slog.v(TAG,
7941                    "Removing provider requested by "
7942                    + conn.client.processName + " from process "
7943                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7944                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7945            if (stable) {
7946                conn.stableCount--;
7947            } else {
7948                conn.unstableCount--;
7949            }
7950            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7951                cpr.connections.remove(conn);
7952                conn.client.conProviders.remove(conn);
7953                return true;
7954            }
7955            return false;
7956        }
7957        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7958        return false;
7959    }
7960
7961    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7962            String name, IBinder token, boolean stable, int userId) {
7963        ContentProviderRecord cpr;
7964        ContentProviderConnection conn = null;
7965        ProviderInfo cpi = null;
7966
7967        synchronized(this) {
7968            ProcessRecord r = null;
7969            if (caller != null) {
7970                r = getRecordForAppLocked(caller);
7971                if (r == null) {
7972                    throw new SecurityException(
7973                            "Unable to find app for caller " + caller
7974                          + " (pid=" + Binder.getCallingPid()
7975                          + ") when getting content provider " + name);
7976                }
7977            }
7978
7979            boolean checkCrossUser = true;
7980
7981            // First check if this content provider has been published...
7982            cpr = mProviderMap.getProviderByName(name, userId);
7983            // If that didn't work, check if it exists for user 0 and then
7984            // verify that it's a singleton provider before using it.
7985            if (cpr == null && userId != UserHandle.USER_OWNER) {
7986                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7987                if (cpr != null) {
7988                    cpi = cpr.info;
7989                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7990                            cpi.name, cpi.flags)
7991                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7992                        userId = UserHandle.USER_OWNER;
7993                        checkCrossUser = false;
7994                    } else {
7995                        cpr = null;
7996                        cpi = null;
7997                    }
7998                }
7999            }
8000
8001            boolean providerRunning = cpr != null;
8002            if (providerRunning) {
8003                cpi = cpr.info;
8004                String msg;
8005                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8006                        != null) {
8007                    throw new SecurityException(msg);
8008                }
8009
8010                if (r != null && cpr.canRunHere(r)) {
8011                    // This provider has been published or is in the process
8012                    // of being published...  but it is also allowed to run
8013                    // in the caller's process, so don't make a connection
8014                    // and just let the caller instantiate its own instance.
8015                    ContentProviderHolder holder = cpr.newHolder(null);
8016                    // don't give caller the provider object, it needs
8017                    // to make its own.
8018                    holder.provider = null;
8019                    return holder;
8020                }
8021
8022                final long origId = Binder.clearCallingIdentity();
8023
8024                // In this case the provider instance already exists, so we can
8025                // return it right away.
8026                conn = incProviderCountLocked(r, cpr, token, stable);
8027                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8028                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8029                        // If this is a perceptible app accessing the provider,
8030                        // make sure to count it as being accessed and thus
8031                        // back up on the LRU list.  This is good because
8032                        // content providers are often expensive to start.
8033                        updateLruProcessLocked(cpr.proc, false, null);
8034                    }
8035                }
8036
8037                if (cpr.proc != null) {
8038                    if (false) {
8039                        if (cpr.name.flattenToShortString().equals(
8040                                "com.android.providers.calendar/.CalendarProvider2")) {
8041                            Slog.v(TAG, "****************** KILLING "
8042                                + cpr.name.flattenToShortString());
8043                            Process.killProcess(cpr.proc.pid);
8044                        }
8045                    }
8046                    boolean success = updateOomAdjLocked(cpr.proc);
8047                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8048                    // NOTE: there is still a race here where a signal could be
8049                    // pending on the process even though we managed to update its
8050                    // adj level.  Not sure what to do about this, but at least
8051                    // the race is now smaller.
8052                    if (!success) {
8053                        // Uh oh...  it looks like the provider's process
8054                        // has been killed on us.  We need to wait for a new
8055                        // process to be started, and make sure its death
8056                        // doesn't kill our process.
8057                        Slog.i(TAG,
8058                                "Existing provider " + cpr.name.flattenToShortString()
8059                                + " is crashing; detaching " + r);
8060                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8061                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8062                        if (!lastRef) {
8063                            // This wasn't the last ref our process had on
8064                            // the provider...  we have now been killed, bail.
8065                            return null;
8066                        }
8067                        providerRunning = false;
8068                        conn = null;
8069                    }
8070                }
8071
8072                Binder.restoreCallingIdentity(origId);
8073            }
8074
8075            boolean singleton;
8076            if (!providerRunning) {
8077                try {
8078                    cpi = AppGlobals.getPackageManager().
8079                        resolveContentProvider(name,
8080                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8081                } catch (RemoteException ex) {
8082                }
8083                if (cpi == null) {
8084                    return null;
8085                }
8086                // If the provider is a singleton AND
8087                // (it's a call within the same user || the provider is a
8088                // privileged app)
8089                // Then allow connecting to the singleton provider
8090                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8091                        cpi.name, cpi.flags)
8092                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8093                if (singleton) {
8094                    userId = UserHandle.USER_OWNER;
8095                }
8096                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8097
8098                String msg;
8099                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8100                        != null) {
8101                    throw new SecurityException(msg);
8102                }
8103
8104                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8105                        && !cpi.processName.equals("system")) {
8106                    // If this content provider does not run in the system
8107                    // process, and the system is not yet ready to run other
8108                    // processes, then fail fast instead of hanging.
8109                    throw new IllegalArgumentException(
8110                            "Attempt to launch content provider before system ready");
8111                }
8112
8113                // Make sure that the user who owns this provider is started.  If not,
8114                // we don't want to allow it to run.
8115                if (mStartedUsers.get(userId) == null) {
8116                    Slog.w(TAG, "Unable to launch app "
8117                            + cpi.applicationInfo.packageName + "/"
8118                            + cpi.applicationInfo.uid + " for provider "
8119                            + name + ": user " + userId + " is stopped");
8120                    return null;
8121                }
8122
8123                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8124                cpr = mProviderMap.getProviderByClass(comp, userId);
8125                final boolean firstClass = cpr == null;
8126                if (firstClass) {
8127                    try {
8128                        ApplicationInfo ai =
8129                            AppGlobals.getPackageManager().
8130                                getApplicationInfo(
8131                                        cpi.applicationInfo.packageName,
8132                                        STOCK_PM_FLAGS, userId);
8133                        if (ai == null) {
8134                            Slog.w(TAG, "No package info for content provider "
8135                                    + cpi.name);
8136                            return null;
8137                        }
8138                        ai = getAppInfoForUser(ai, userId);
8139                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8140                    } catch (RemoteException ex) {
8141                        // pm is in same process, this will never happen.
8142                    }
8143                }
8144
8145                if (r != null && cpr.canRunHere(r)) {
8146                    // If this is a multiprocess provider, then just return its
8147                    // info and allow the caller to instantiate it.  Only do
8148                    // this if the provider is the same user as the caller's
8149                    // process, or can run as root (so can be in any process).
8150                    return cpr.newHolder(null);
8151                }
8152
8153                if (DEBUG_PROVIDER) {
8154                    RuntimeException e = new RuntimeException("here");
8155                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8156                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8157                }
8158
8159                // This is single process, and our app is now connecting to it.
8160                // See if we are already in the process of launching this
8161                // provider.
8162                final int N = mLaunchingProviders.size();
8163                int i;
8164                for (i=0; i<N; i++) {
8165                    if (mLaunchingProviders.get(i) == cpr) {
8166                        break;
8167                    }
8168                }
8169
8170                // If the provider is not already being launched, then get it
8171                // started.
8172                if (i >= N) {
8173                    final long origId = Binder.clearCallingIdentity();
8174
8175                    try {
8176                        // Content provider is now in use, its package can't be stopped.
8177                        try {
8178                            AppGlobals.getPackageManager().setPackageStoppedState(
8179                                    cpr.appInfo.packageName, false, userId);
8180                        } catch (RemoteException e) {
8181                        } catch (IllegalArgumentException e) {
8182                            Slog.w(TAG, "Failed trying to unstop package "
8183                                    + cpr.appInfo.packageName + ": " + e);
8184                        }
8185
8186                        // Use existing process if already started
8187                        ProcessRecord proc = getProcessRecordLocked(
8188                                cpi.processName, cpr.appInfo.uid, false);
8189                        if (proc != null && proc.thread != null) {
8190                            if (DEBUG_PROVIDER) {
8191                                Slog.d(TAG, "Installing in existing process " + proc);
8192                            }
8193                            proc.pubProviders.put(cpi.name, cpr);
8194                            try {
8195                                proc.thread.scheduleInstallProvider(cpi);
8196                            } catch (RemoteException e) {
8197                            }
8198                        } else {
8199                            proc = startProcessLocked(cpi.processName,
8200                                    cpr.appInfo, false, 0, "content provider",
8201                                    new ComponentName(cpi.applicationInfo.packageName,
8202                                            cpi.name), false, false, false);
8203                            if (proc == null) {
8204                                Slog.w(TAG, "Unable to launch app "
8205                                        + cpi.applicationInfo.packageName + "/"
8206                                        + cpi.applicationInfo.uid + " for provider "
8207                                        + name + ": process is bad");
8208                                return null;
8209                            }
8210                        }
8211                        cpr.launchingApp = proc;
8212                        mLaunchingProviders.add(cpr);
8213                    } finally {
8214                        Binder.restoreCallingIdentity(origId);
8215                    }
8216                }
8217
8218                // Make sure the provider is published (the same provider class
8219                // may be published under multiple names).
8220                if (firstClass) {
8221                    mProviderMap.putProviderByClass(comp, cpr);
8222                }
8223
8224                mProviderMap.putProviderByName(name, cpr);
8225                conn = incProviderCountLocked(r, cpr, token, stable);
8226                if (conn != null) {
8227                    conn.waiting = true;
8228                }
8229            }
8230        }
8231
8232        // Wait for the provider to be published...
8233        synchronized (cpr) {
8234            while (cpr.provider == null) {
8235                if (cpr.launchingApp == null) {
8236                    Slog.w(TAG, "Unable to launch app "
8237                            + cpi.applicationInfo.packageName + "/"
8238                            + cpi.applicationInfo.uid + " for provider "
8239                            + name + ": launching app became null");
8240                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8241                            UserHandle.getUserId(cpi.applicationInfo.uid),
8242                            cpi.applicationInfo.packageName,
8243                            cpi.applicationInfo.uid, name);
8244                    return null;
8245                }
8246                try {
8247                    if (DEBUG_MU) {
8248                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8249                                + cpr.launchingApp);
8250                    }
8251                    if (conn != null) {
8252                        conn.waiting = true;
8253                    }
8254                    cpr.wait();
8255                } catch (InterruptedException ex) {
8256                } finally {
8257                    if (conn != null) {
8258                        conn.waiting = false;
8259                    }
8260                }
8261            }
8262        }
8263        return cpr != null ? cpr.newHolder(conn) : null;
8264    }
8265
8266    @Override
8267    public final ContentProviderHolder getContentProvider(
8268            IApplicationThread caller, String name, int userId, boolean stable) {
8269        enforceNotIsolatedCaller("getContentProvider");
8270        if (caller == null) {
8271            String msg = "null IApplicationThread when getting content provider "
8272                    + name;
8273            Slog.w(TAG, msg);
8274            throw new SecurityException(msg);
8275        }
8276        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8277        // with cross-user grant.
8278        return getContentProviderImpl(caller, name, null, stable, userId);
8279    }
8280
8281    public ContentProviderHolder getContentProviderExternal(
8282            String name, int userId, IBinder token) {
8283        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8284            "Do not have permission in call getContentProviderExternal()");
8285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8286                false, true, "getContentProvider", null);
8287        return getContentProviderExternalUnchecked(name, token, userId);
8288    }
8289
8290    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8291            IBinder token, int userId) {
8292        return getContentProviderImpl(null, name, token, true, userId);
8293    }
8294
8295    /**
8296     * Drop a content provider from a ProcessRecord's bookkeeping
8297     */
8298    public void removeContentProvider(IBinder connection, boolean stable) {
8299        enforceNotIsolatedCaller("removeContentProvider");
8300        long ident = Binder.clearCallingIdentity();
8301        try {
8302            synchronized (this) {
8303                ContentProviderConnection conn;
8304                try {
8305                    conn = (ContentProviderConnection)connection;
8306                } catch (ClassCastException e) {
8307                    String msg ="removeContentProvider: " + connection
8308                            + " not a ContentProviderConnection";
8309                    Slog.w(TAG, msg);
8310                    throw new IllegalArgumentException(msg);
8311                }
8312                if (conn == null) {
8313                    throw new NullPointerException("connection is null");
8314                }
8315                if (decProviderCountLocked(conn, null, null, stable)) {
8316                    updateOomAdjLocked();
8317                }
8318            }
8319        } finally {
8320            Binder.restoreCallingIdentity(ident);
8321        }
8322    }
8323
8324    public void removeContentProviderExternal(String name, IBinder token) {
8325        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8326            "Do not have permission in call removeContentProviderExternal()");
8327        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8328    }
8329
8330    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8331        synchronized (this) {
8332            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8333            if(cpr == null) {
8334                //remove from mProvidersByClass
8335                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8336                return;
8337            }
8338
8339            //update content provider record entry info
8340            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8341            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8342            if (localCpr.hasExternalProcessHandles()) {
8343                if (localCpr.removeExternalProcessHandleLocked(token)) {
8344                    updateOomAdjLocked();
8345                } else {
8346                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8347                            + " with no external reference for token: "
8348                            + token + ".");
8349                }
8350            } else {
8351                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8352                        + " with no external references.");
8353            }
8354        }
8355    }
8356
8357    public final void publishContentProviders(IApplicationThread caller,
8358            List<ContentProviderHolder> providers) {
8359        if (providers == null) {
8360            return;
8361        }
8362
8363        enforceNotIsolatedCaller("publishContentProviders");
8364        synchronized (this) {
8365            final ProcessRecord r = getRecordForAppLocked(caller);
8366            if (DEBUG_MU)
8367                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8368            if (r == null) {
8369                throw new SecurityException(
8370                        "Unable to find app for caller " + caller
8371                      + " (pid=" + Binder.getCallingPid()
8372                      + ") when publishing content providers");
8373            }
8374
8375            final long origId = Binder.clearCallingIdentity();
8376
8377            final int N = providers.size();
8378            for (int i=0; i<N; i++) {
8379                ContentProviderHolder src = providers.get(i);
8380                if (src == null || src.info == null || src.provider == null) {
8381                    continue;
8382                }
8383                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8384                if (DEBUG_MU)
8385                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8386                if (dst != null) {
8387                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8388                    mProviderMap.putProviderByClass(comp, dst);
8389                    String names[] = dst.info.authority.split(";");
8390                    for (int j = 0; j < names.length; j++) {
8391                        mProviderMap.putProviderByName(names[j], dst);
8392                    }
8393
8394                    int NL = mLaunchingProviders.size();
8395                    int j;
8396                    for (j=0; j<NL; j++) {
8397                        if (mLaunchingProviders.get(j) == dst) {
8398                            mLaunchingProviders.remove(j);
8399                            j--;
8400                            NL--;
8401                        }
8402                    }
8403                    synchronized (dst) {
8404                        dst.provider = src.provider;
8405                        dst.proc = r;
8406                        dst.notifyAll();
8407                    }
8408                    updateOomAdjLocked(r);
8409                }
8410            }
8411
8412            Binder.restoreCallingIdentity(origId);
8413        }
8414    }
8415
8416    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8417        ContentProviderConnection conn;
8418        try {
8419            conn = (ContentProviderConnection)connection;
8420        } catch (ClassCastException e) {
8421            String msg ="refContentProvider: " + connection
8422                    + " not a ContentProviderConnection";
8423            Slog.w(TAG, msg);
8424            throw new IllegalArgumentException(msg);
8425        }
8426        if (conn == null) {
8427            throw new NullPointerException("connection is null");
8428        }
8429
8430        synchronized (this) {
8431            if (stable > 0) {
8432                conn.numStableIncs += stable;
8433            }
8434            stable = conn.stableCount + stable;
8435            if (stable < 0) {
8436                throw new IllegalStateException("stableCount < 0: " + stable);
8437            }
8438
8439            if (unstable > 0) {
8440                conn.numUnstableIncs += unstable;
8441            }
8442            unstable = conn.unstableCount + unstable;
8443            if (unstable < 0) {
8444                throw new IllegalStateException("unstableCount < 0: " + unstable);
8445            }
8446
8447            if ((stable+unstable) <= 0) {
8448                throw new IllegalStateException("ref counts can't go to zero here: stable="
8449                        + stable + " unstable=" + unstable);
8450            }
8451            conn.stableCount = stable;
8452            conn.unstableCount = unstable;
8453            return !conn.dead;
8454        }
8455    }
8456
8457    public void unstableProviderDied(IBinder connection) {
8458        ContentProviderConnection conn;
8459        try {
8460            conn = (ContentProviderConnection)connection;
8461        } catch (ClassCastException e) {
8462            String msg ="refContentProvider: " + connection
8463                    + " not a ContentProviderConnection";
8464            Slog.w(TAG, msg);
8465            throw new IllegalArgumentException(msg);
8466        }
8467        if (conn == null) {
8468            throw new NullPointerException("connection is null");
8469        }
8470
8471        // Safely retrieve the content provider associated with the connection.
8472        IContentProvider provider;
8473        synchronized (this) {
8474            provider = conn.provider.provider;
8475        }
8476
8477        if (provider == null) {
8478            // Um, yeah, we're way ahead of you.
8479            return;
8480        }
8481
8482        // Make sure the caller is being honest with us.
8483        if (provider.asBinder().pingBinder()) {
8484            // Er, no, still looks good to us.
8485            synchronized (this) {
8486                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8487                        + " says " + conn + " died, but we don't agree");
8488                return;
8489            }
8490        }
8491
8492        // Well look at that!  It's dead!
8493        synchronized (this) {
8494            if (conn.provider.provider != provider) {
8495                // But something changed...  good enough.
8496                return;
8497            }
8498
8499            ProcessRecord proc = conn.provider.proc;
8500            if (proc == null || proc.thread == null) {
8501                // Seems like the process is already cleaned up.
8502                return;
8503            }
8504
8505            // As far as we're concerned, this is just like receiving a
8506            // death notification...  just a bit prematurely.
8507            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8508                    + ") early provider death");
8509            final long ident = Binder.clearCallingIdentity();
8510            try {
8511                appDiedLocked(proc, proc.pid, proc.thread);
8512            } finally {
8513                Binder.restoreCallingIdentity(ident);
8514            }
8515        }
8516    }
8517
8518    @Override
8519    public void appNotRespondingViaProvider(IBinder connection) {
8520        enforceCallingPermission(
8521                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8522
8523        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8524        if (conn == null) {
8525            Slog.w(TAG, "ContentProviderConnection is null");
8526            return;
8527        }
8528
8529        final ProcessRecord host = conn.provider.proc;
8530        if (host == null) {
8531            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8532            return;
8533        }
8534
8535        final long token = Binder.clearCallingIdentity();
8536        try {
8537            appNotResponding(host, null, null, false, "ContentProvider not responding");
8538        } finally {
8539            Binder.restoreCallingIdentity(token);
8540        }
8541    }
8542
8543    public final void installSystemProviders() {
8544        List<ProviderInfo> providers;
8545        synchronized (this) {
8546            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8547            providers = generateApplicationProvidersLocked(app);
8548            if (providers != null) {
8549                for (int i=providers.size()-1; i>=0; i--) {
8550                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8551                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8552                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8553                                + ": not system .apk");
8554                        providers.remove(i);
8555                    }
8556                }
8557            }
8558        }
8559        if (providers != null) {
8560            mSystemThread.installSystemProviders(providers);
8561        }
8562
8563        mCoreSettingsObserver = new CoreSettingsObserver(this);
8564
8565        mUsageStatsService.monitorPackages();
8566    }
8567
8568    /**
8569     * Allows app to retrieve the MIME type of a URI without having permission
8570     * to access its content provider.
8571     *
8572     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8573     *
8574     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8575     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8576     */
8577    public String getProviderMimeType(Uri uri, int userId) {
8578        enforceNotIsolatedCaller("getProviderMimeType");
8579        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8580                userId, false, true, "getProviderMimeType", null);
8581        final String name = uri.getAuthority();
8582        final long ident = Binder.clearCallingIdentity();
8583        ContentProviderHolder holder = null;
8584
8585        try {
8586            holder = getContentProviderExternalUnchecked(name, null, userId);
8587            if (holder != null) {
8588                return holder.provider.getType(uri);
8589            }
8590        } catch (RemoteException e) {
8591            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8592            return null;
8593        } finally {
8594            if (holder != null) {
8595                removeContentProviderExternalUnchecked(name, null, userId);
8596            }
8597            Binder.restoreCallingIdentity(ident);
8598        }
8599
8600        return null;
8601    }
8602
8603    // =========================================================
8604    // GLOBAL MANAGEMENT
8605    // =========================================================
8606
8607    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8608            boolean isolated) {
8609        String proc = customProcess != null ? customProcess : info.processName;
8610        BatteryStatsImpl.Uid.Proc ps = null;
8611        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8612        int uid = info.uid;
8613        if (isolated) {
8614            int userId = UserHandle.getUserId(uid);
8615            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8616            while (true) {
8617                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8618                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8619                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8620                }
8621                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8622                mNextIsolatedProcessUid++;
8623                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8624                    // No process for this uid, use it.
8625                    break;
8626                }
8627                stepsLeft--;
8628                if (stepsLeft <= 0) {
8629                    return null;
8630                }
8631            }
8632        }
8633        return new ProcessRecord(stats, info, proc, uid);
8634    }
8635
8636    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8637            String abiOverride) {
8638        ProcessRecord app;
8639        if (!isolated) {
8640            app = getProcessRecordLocked(info.processName, info.uid, true);
8641        } else {
8642            app = null;
8643        }
8644
8645        if (app == null) {
8646            app = newProcessRecordLocked(info, null, isolated);
8647            mProcessNames.put(info.processName, app.uid, app);
8648            if (isolated) {
8649                mIsolatedProcesses.put(app.uid, app);
8650            }
8651            updateLruProcessLocked(app, false, null);
8652            updateOomAdjLocked();
8653        }
8654
8655        // This package really, really can not be stopped.
8656        try {
8657            AppGlobals.getPackageManager().setPackageStoppedState(
8658                    info.packageName, false, UserHandle.getUserId(app.uid));
8659        } catch (RemoteException e) {
8660        } catch (IllegalArgumentException e) {
8661            Slog.w(TAG, "Failed trying to unstop package "
8662                    + info.packageName + ": " + e);
8663        }
8664
8665        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8666                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8667            app.persistent = true;
8668            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8669        }
8670        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8671            mPersistentStartingProcesses.add(app);
8672            startProcessLocked(app, "added application", app.processName,
8673                    abiOverride);
8674        }
8675
8676        return app;
8677    }
8678
8679    public void unhandledBack() {
8680        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8681                "unhandledBack()");
8682
8683        synchronized(this) {
8684            final long origId = Binder.clearCallingIdentity();
8685            try {
8686                getFocusedStack().unhandledBackLocked();
8687            } finally {
8688                Binder.restoreCallingIdentity(origId);
8689            }
8690        }
8691    }
8692
8693    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8694        enforceNotIsolatedCaller("openContentUri");
8695        final int userId = UserHandle.getCallingUserId();
8696        String name = uri.getAuthority();
8697        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8698        ParcelFileDescriptor pfd = null;
8699        if (cph != null) {
8700            // We record the binder invoker's uid in thread-local storage before
8701            // going to the content provider to open the file.  Later, in the code
8702            // that handles all permissions checks, we look for this uid and use
8703            // that rather than the Activity Manager's own uid.  The effect is that
8704            // we do the check against the caller's permissions even though it looks
8705            // to the content provider like the Activity Manager itself is making
8706            // the request.
8707            sCallerIdentity.set(new Identity(
8708                    Binder.getCallingPid(), Binder.getCallingUid()));
8709            try {
8710                pfd = cph.provider.openFile(null, uri, "r", null);
8711            } catch (FileNotFoundException e) {
8712                // do nothing; pfd will be returned null
8713            } finally {
8714                // Ensure that whatever happens, we clean up the identity state
8715                sCallerIdentity.remove();
8716            }
8717
8718            // We've got the fd now, so we're done with the provider.
8719            removeContentProviderExternalUnchecked(name, null, userId);
8720        } else {
8721            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8722        }
8723        return pfd;
8724    }
8725
8726    // Actually is sleeping or shutting down or whatever else in the future
8727    // is an inactive state.
8728    public boolean isSleepingOrShuttingDown() {
8729        return mSleeping || mShuttingDown;
8730    }
8731
8732    public boolean isSleeping() {
8733        return mSleeping;
8734    }
8735
8736    void goingToSleep() {
8737        synchronized(this) {
8738            mWentToSleep = true;
8739            updateEventDispatchingLocked();
8740            goToSleepIfNeededLocked();
8741        }
8742    }
8743
8744    void finishRunningVoiceLocked() {
8745        if (mRunningVoice) {
8746            mRunningVoice = false;
8747            goToSleepIfNeededLocked();
8748        }
8749    }
8750
8751    void goToSleepIfNeededLocked() {
8752        if (mWentToSleep && !mRunningVoice) {
8753            if (!mSleeping) {
8754                mSleeping = true;
8755                mStackSupervisor.goingToSleepLocked();
8756
8757                // Initialize the wake times of all processes.
8758                checkExcessivePowerUsageLocked(false);
8759                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8760                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8761                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8762            }
8763        }
8764    }
8765
8766    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8767        mTaskPersister.notify(task, flush);
8768    }
8769
8770    @Override
8771    public boolean shutdown(int timeout) {
8772        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8773                != PackageManager.PERMISSION_GRANTED) {
8774            throw new SecurityException("Requires permission "
8775                    + android.Manifest.permission.SHUTDOWN);
8776        }
8777
8778        boolean timedout = false;
8779
8780        synchronized(this) {
8781            mShuttingDown = true;
8782            updateEventDispatchingLocked();
8783            timedout = mStackSupervisor.shutdownLocked(timeout);
8784        }
8785
8786        mAppOpsService.shutdown();
8787        mUsageStatsService.shutdown();
8788        mBatteryStatsService.shutdown();
8789        synchronized (this) {
8790            mProcessStats.shutdownLocked();
8791        }
8792        notifyTaskPersisterLocked(null, true);
8793
8794        return timedout;
8795    }
8796
8797    public final void activitySlept(IBinder token) {
8798        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8799
8800        final long origId = Binder.clearCallingIdentity();
8801
8802        synchronized (this) {
8803            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8804            if (r != null) {
8805                mStackSupervisor.activitySleptLocked(r);
8806            }
8807        }
8808
8809        Binder.restoreCallingIdentity(origId);
8810    }
8811
8812    void logLockScreen(String msg) {
8813        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8814                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8815                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8816                mStackSupervisor.mDismissKeyguardOnNextActivity);
8817    }
8818
8819    private void comeOutOfSleepIfNeededLocked() {
8820        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8821            if (mSleeping) {
8822                mSleeping = false;
8823                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8824            }
8825        }
8826    }
8827
8828    void wakingUp() {
8829        synchronized(this) {
8830            mWentToSleep = false;
8831            updateEventDispatchingLocked();
8832            comeOutOfSleepIfNeededLocked();
8833        }
8834    }
8835
8836    void startRunningVoiceLocked() {
8837        if (!mRunningVoice) {
8838            mRunningVoice = true;
8839            comeOutOfSleepIfNeededLocked();
8840        }
8841    }
8842
8843    private void updateEventDispatchingLocked() {
8844        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8845    }
8846
8847    public void setLockScreenShown(boolean shown) {
8848        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8849                != PackageManager.PERMISSION_GRANTED) {
8850            throw new SecurityException("Requires permission "
8851                    + android.Manifest.permission.DEVICE_POWER);
8852        }
8853
8854        synchronized(this) {
8855            long ident = Binder.clearCallingIdentity();
8856            try {
8857                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8858                mLockScreenShown = shown;
8859                comeOutOfSleepIfNeededLocked();
8860            } finally {
8861                Binder.restoreCallingIdentity(ident);
8862            }
8863        }
8864    }
8865
8866    public void stopAppSwitches() {
8867        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8868                != PackageManager.PERMISSION_GRANTED) {
8869            throw new SecurityException("Requires permission "
8870                    + android.Manifest.permission.STOP_APP_SWITCHES);
8871        }
8872
8873        synchronized(this) {
8874            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8875                    + APP_SWITCH_DELAY_TIME;
8876            mDidAppSwitch = false;
8877            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8878            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8879            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8880        }
8881    }
8882
8883    public void resumeAppSwitches() {
8884        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8885                != PackageManager.PERMISSION_GRANTED) {
8886            throw new SecurityException("Requires permission "
8887                    + android.Manifest.permission.STOP_APP_SWITCHES);
8888        }
8889
8890        synchronized(this) {
8891            // Note that we don't execute any pending app switches... we will
8892            // let those wait until either the timeout, or the next start
8893            // activity request.
8894            mAppSwitchesAllowedTime = 0;
8895        }
8896    }
8897
8898    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8899            String name) {
8900        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8901            return true;
8902        }
8903
8904        final int perm = checkComponentPermission(
8905                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8906                callingUid, -1, true);
8907        if (perm == PackageManager.PERMISSION_GRANTED) {
8908            return true;
8909        }
8910
8911        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8912        return false;
8913    }
8914
8915    public void setDebugApp(String packageName, boolean waitForDebugger,
8916            boolean persistent) {
8917        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8918                "setDebugApp()");
8919
8920        long ident = Binder.clearCallingIdentity();
8921        try {
8922            // Note that this is not really thread safe if there are multiple
8923            // callers into it at the same time, but that's not a situation we
8924            // care about.
8925            if (persistent) {
8926                final ContentResolver resolver = mContext.getContentResolver();
8927                Settings.Global.putString(
8928                    resolver, Settings.Global.DEBUG_APP,
8929                    packageName);
8930                Settings.Global.putInt(
8931                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8932                    waitForDebugger ? 1 : 0);
8933            }
8934
8935            synchronized (this) {
8936                if (!persistent) {
8937                    mOrigDebugApp = mDebugApp;
8938                    mOrigWaitForDebugger = mWaitForDebugger;
8939                }
8940                mDebugApp = packageName;
8941                mWaitForDebugger = waitForDebugger;
8942                mDebugTransient = !persistent;
8943                if (packageName != null) {
8944                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8945                            false, UserHandle.USER_ALL, "set debug app");
8946                }
8947            }
8948        } finally {
8949            Binder.restoreCallingIdentity(ident);
8950        }
8951    }
8952
8953    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8954        synchronized (this) {
8955            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8956            if (!isDebuggable) {
8957                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8958                    throw new SecurityException("Process not debuggable: " + app.packageName);
8959                }
8960            }
8961
8962            mOpenGlTraceApp = processName;
8963        }
8964    }
8965
8966    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8967            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8968        synchronized (this) {
8969            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8970            if (!isDebuggable) {
8971                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8972                    throw new SecurityException("Process not debuggable: " + app.packageName);
8973                }
8974            }
8975            mProfileApp = processName;
8976            mProfileFile = profileFile;
8977            if (mProfileFd != null) {
8978                try {
8979                    mProfileFd.close();
8980                } catch (IOException e) {
8981                }
8982                mProfileFd = null;
8983            }
8984            mProfileFd = profileFd;
8985            mProfileType = 0;
8986            mAutoStopProfiler = autoStopProfiler;
8987        }
8988    }
8989
8990    @Override
8991    public void setAlwaysFinish(boolean enabled) {
8992        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8993                "setAlwaysFinish()");
8994
8995        Settings.Global.putInt(
8996                mContext.getContentResolver(),
8997                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8998
8999        synchronized (this) {
9000            mAlwaysFinishActivities = enabled;
9001        }
9002    }
9003
9004    @Override
9005    public void setActivityController(IActivityController controller) {
9006        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9007                "setActivityController()");
9008        synchronized (this) {
9009            mController = controller;
9010            Watchdog.getInstance().setActivityController(controller);
9011        }
9012    }
9013
9014    @Override
9015    public void setUserIsMonkey(boolean userIsMonkey) {
9016        synchronized (this) {
9017            synchronized (mPidsSelfLocked) {
9018                final int callingPid = Binder.getCallingPid();
9019                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9020                if (precessRecord == null) {
9021                    throw new SecurityException("Unknown process: " + callingPid);
9022                }
9023                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9024                    throw new SecurityException("Only an instrumentation process "
9025                            + "with a UiAutomation can call setUserIsMonkey");
9026                }
9027            }
9028            mUserIsMonkey = userIsMonkey;
9029        }
9030    }
9031
9032    @Override
9033    public boolean isUserAMonkey() {
9034        synchronized (this) {
9035            // If there is a controller also implies the user is a monkey.
9036            return (mUserIsMonkey || mController != null);
9037        }
9038    }
9039
9040    public void requestBugReport() {
9041        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9042        SystemProperties.set("ctl.start", "bugreport");
9043    }
9044
9045    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9046        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9047    }
9048
9049    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9050        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9051            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9052        }
9053        return KEY_DISPATCHING_TIMEOUT;
9054    }
9055
9056    @Override
9057    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9058        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9059                != PackageManager.PERMISSION_GRANTED) {
9060            throw new SecurityException("Requires permission "
9061                    + android.Manifest.permission.FILTER_EVENTS);
9062        }
9063        ProcessRecord proc;
9064        long timeout;
9065        synchronized (this) {
9066            synchronized (mPidsSelfLocked) {
9067                proc = mPidsSelfLocked.get(pid);
9068            }
9069            timeout = getInputDispatchingTimeoutLocked(proc);
9070        }
9071
9072        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9073            return -1;
9074        }
9075
9076        return timeout;
9077    }
9078
9079    /**
9080     * Handle input dispatching timeouts.
9081     * Returns whether input dispatching should be aborted or not.
9082     */
9083    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9084            final ActivityRecord activity, final ActivityRecord parent,
9085            final boolean aboveSystem, String reason) {
9086        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9087                != PackageManager.PERMISSION_GRANTED) {
9088            throw new SecurityException("Requires permission "
9089                    + android.Manifest.permission.FILTER_EVENTS);
9090        }
9091
9092        final String annotation;
9093        if (reason == null) {
9094            annotation = "Input dispatching timed out";
9095        } else {
9096            annotation = "Input dispatching timed out (" + reason + ")";
9097        }
9098
9099        if (proc != null) {
9100            synchronized (this) {
9101                if (proc.debugging) {
9102                    return false;
9103                }
9104
9105                if (mDidDexOpt) {
9106                    // Give more time since we were dexopting.
9107                    mDidDexOpt = false;
9108                    return false;
9109                }
9110
9111                if (proc.instrumentationClass != null) {
9112                    Bundle info = new Bundle();
9113                    info.putString("shortMsg", "keyDispatchingTimedOut");
9114                    info.putString("longMsg", annotation);
9115                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9116                    return true;
9117                }
9118            }
9119            mHandler.post(new Runnable() {
9120                @Override
9121                public void run() {
9122                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9123                }
9124            });
9125        }
9126
9127        return true;
9128    }
9129
9130    public Bundle getAssistContextExtras(int requestType) {
9131        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9132                "getAssistContextExtras()");
9133        PendingAssistExtras pae;
9134        Bundle extras = new Bundle();
9135        synchronized (this) {
9136            ActivityRecord activity = getFocusedStack().mResumedActivity;
9137            if (activity == null) {
9138                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9139                return null;
9140            }
9141            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9142            if (activity.app == null || activity.app.thread == null) {
9143                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9144                return extras;
9145            }
9146            if (activity.app.pid == Binder.getCallingPid()) {
9147                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9148                return extras;
9149            }
9150            pae = new PendingAssistExtras(activity);
9151            try {
9152                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9153                        requestType);
9154                mPendingAssistExtras.add(pae);
9155                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9156            } catch (RemoteException e) {
9157                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9158                return extras;
9159            }
9160        }
9161        synchronized (pae) {
9162            while (!pae.haveResult) {
9163                try {
9164                    pae.wait();
9165                } catch (InterruptedException e) {
9166                }
9167            }
9168            if (pae.result != null) {
9169                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9170            }
9171        }
9172        synchronized (this) {
9173            mPendingAssistExtras.remove(pae);
9174            mHandler.removeCallbacks(pae);
9175        }
9176        return extras;
9177    }
9178
9179    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9180        PendingAssistExtras pae = (PendingAssistExtras)token;
9181        synchronized (pae) {
9182            pae.result = extras;
9183            pae.haveResult = true;
9184            pae.notifyAll();
9185        }
9186    }
9187
9188    public void registerProcessObserver(IProcessObserver observer) {
9189        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9190                "registerProcessObserver()");
9191        synchronized (this) {
9192            mProcessObservers.register(observer);
9193        }
9194    }
9195
9196    @Override
9197    public void unregisterProcessObserver(IProcessObserver observer) {
9198        synchronized (this) {
9199            mProcessObservers.unregister(observer);
9200        }
9201    }
9202
9203    @Override
9204    public boolean convertFromTranslucent(IBinder token) {
9205        final long origId = Binder.clearCallingIdentity();
9206        try {
9207            synchronized (this) {
9208                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9209                if (r == null) {
9210                    return false;
9211                }
9212                if (r.changeWindowTranslucency(true)) {
9213                    mWindowManager.setAppFullscreen(token, true);
9214                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9215                    return true;
9216                }
9217                return false;
9218            }
9219        } finally {
9220            Binder.restoreCallingIdentity(origId);
9221        }
9222    }
9223
9224    @Override
9225    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9226        final long origId = Binder.clearCallingIdentity();
9227        try {
9228            synchronized (this) {
9229                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9230                if (r == null) {
9231                    return false;
9232                }
9233                if (r.changeWindowTranslucency(false)) {
9234                    r.task.stack.convertToTranslucent(r, options);
9235                    mWindowManager.setAppFullscreen(token, false);
9236                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9237                    return true;
9238                }
9239                return false;
9240            }
9241        } finally {
9242            Binder.restoreCallingIdentity(origId);
9243        }
9244    }
9245
9246    @Override
9247    public ActivityOptions getActivityOptions(IBinder token) {
9248        final long origId = Binder.clearCallingIdentity();
9249        try {
9250            synchronized (this) {
9251                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9252                if (r != null) {
9253                    final ActivityOptions activityOptions = r.pendingOptions;
9254                    r.pendingOptions = null;
9255                    return activityOptions;
9256                }
9257                return null;
9258            }
9259        } finally {
9260            Binder.restoreCallingIdentity(origId);
9261        }
9262    }
9263
9264    @Override
9265    public void setImmersive(IBinder token, boolean immersive) {
9266        synchronized(this) {
9267            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9268            if (r == null) {
9269                throw new IllegalArgumentException();
9270            }
9271            r.immersive = immersive;
9272
9273            // update associated state if we're frontmost
9274            if (r == mFocusedActivity) {
9275                if (DEBUG_IMMERSIVE) {
9276                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9277                }
9278                applyUpdateLockStateLocked(r);
9279            }
9280        }
9281    }
9282
9283    @Override
9284    public boolean isImmersive(IBinder token) {
9285        synchronized (this) {
9286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9287            if (r == null) {
9288                throw new IllegalArgumentException();
9289            }
9290            return r.immersive;
9291        }
9292    }
9293
9294    public boolean isTopActivityImmersive() {
9295        enforceNotIsolatedCaller("startActivity");
9296        synchronized (this) {
9297            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9298            return (r != null) ? r.immersive : false;
9299        }
9300    }
9301
9302    public final void enterSafeMode() {
9303        synchronized(this) {
9304            // It only makes sense to do this before the system is ready
9305            // and started launching other packages.
9306            if (!mSystemReady) {
9307                try {
9308                    AppGlobals.getPackageManager().enterSafeMode();
9309                } catch (RemoteException e) {
9310                }
9311            }
9312
9313            mSafeMode = true;
9314        }
9315    }
9316
9317    public final void showSafeModeOverlay() {
9318        View v = LayoutInflater.from(mContext).inflate(
9319                com.android.internal.R.layout.safe_mode, null);
9320        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9321        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9322        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9323        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9324        lp.gravity = Gravity.BOTTOM | Gravity.START;
9325        lp.format = v.getBackground().getOpacity();
9326        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9327                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9328        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9329        ((WindowManager)mContext.getSystemService(
9330                Context.WINDOW_SERVICE)).addView(v, lp);
9331    }
9332
9333    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9334        if (!(sender instanceof PendingIntentRecord)) {
9335            return;
9336        }
9337        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9338        synchronized (stats) {
9339            if (mBatteryStatsService.isOnBattery()) {
9340                mBatteryStatsService.enforceCallingPermission();
9341                PendingIntentRecord rec = (PendingIntentRecord)sender;
9342                int MY_UID = Binder.getCallingUid();
9343                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9344                BatteryStatsImpl.Uid.Pkg pkg =
9345                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9346                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9347                pkg.incWakeupsLocked();
9348            }
9349        }
9350    }
9351
9352    public boolean killPids(int[] pids, String pReason, boolean secure) {
9353        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9354            throw new SecurityException("killPids only available to the system");
9355        }
9356        String reason = (pReason == null) ? "Unknown" : pReason;
9357        // XXX Note: don't acquire main activity lock here, because the window
9358        // manager calls in with its locks held.
9359
9360        boolean killed = false;
9361        synchronized (mPidsSelfLocked) {
9362            int[] types = new int[pids.length];
9363            int worstType = 0;
9364            for (int i=0; i<pids.length; i++) {
9365                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9366                if (proc != null) {
9367                    int type = proc.setAdj;
9368                    types[i] = type;
9369                    if (type > worstType) {
9370                        worstType = type;
9371                    }
9372                }
9373            }
9374
9375            // If the worst oom_adj is somewhere in the cached proc LRU range,
9376            // then constrain it so we will kill all cached procs.
9377            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9378                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9379                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9380            }
9381
9382            // If this is not a secure call, don't let it kill processes that
9383            // are important.
9384            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9385                worstType = ProcessList.SERVICE_ADJ;
9386            }
9387
9388            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9389            for (int i=0; i<pids.length; i++) {
9390                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9391                if (proc == null) {
9392                    continue;
9393                }
9394                int adj = proc.setAdj;
9395                if (adj >= worstType && !proc.killedByAm) {
9396                    killUnneededProcessLocked(proc, reason);
9397                    killed = true;
9398                }
9399            }
9400        }
9401        return killed;
9402    }
9403
9404    @Override
9405    public void killUid(int uid, String reason) {
9406        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9407            throw new SecurityException("killUid only available to the system");
9408        }
9409        synchronized (this) {
9410            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9411                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9412                    reason != null ? reason : "kill uid");
9413        }
9414    }
9415
9416    @Override
9417    public boolean killProcessesBelowForeground(String reason) {
9418        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9419            throw new SecurityException("killProcessesBelowForeground() only available to system");
9420        }
9421
9422        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9423    }
9424
9425    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9426        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9427            throw new SecurityException("killProcessesBelowAdj() only available to system");
9428        }
9429
9430        boolean killed = false;
9431        synchronized (mPidsSelfLocked) {
9432            final int size = mPidsSelfLocked.size();
9433            for (int i = 0; i < size; i++) {
9434                final int pid = mPidsSelfLocked.keyAt(i);
9435                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9436                if (proc == null) continue;
9437
9438                final int adj = proc.setAdj;
9439                if (adj > belowAdj && !proc.killedByAm) {
9440                    killUnneededProcessLocked(proc, reason);
9441                    killed = true;
9442                }
9443            }
9444        }
9445        return killed;
9446    }
9447
9448    @Override
9449    public void hang(final IBinder who, boolean allowRestart) {
9450        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9451                != PackageManager.PERMISSION_GRANTED) {
9452            throw new SecurityException("Requires permission "
9453                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9454        }
9455
9456        final IBinder.DeathRecipient death = new DeathRecipient() {
9457            @Override
9458            public void binderDied() {
9459                synchronized (this) {
9460                    notifyAll();
9461                }
9462            }
9463        };
9464
9465        try {
9466            who.linkToDeath(death, 0);
9467        } catch (RemoteException e) {
9468            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9469            return;
9470        }
9471
9472        synchronized (this) {
9473            Watchdog.getInstance().setAllowRestart(allowRestart);
9474            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9475            synchronized (death) {
9476                while (who.isBinderAlive()) {
9477                    try {
9478                        death.wait();
9479                    } catch (InterruptedException e) {
9480                    }
9481                }
9482            }
9483            Watchdog.getInstance().setAllowRestart(true);
9484        }
9485    }
9486
9487    @Override
9488    public void restart() {
9489        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9490                != PackageManager.PERMISSION_GRANTED) {
9491            throw new SecurityException("Requires permission "
9492                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9493        }
9494
9495        Log.i(TAG, "Sending shutdown broadcast...");
9496
9497        BroadcastReceiver br = new BroadcastReceiver() {
9498            @Override public void onReceive(Context context, Intent intent) {
9499                // Now the broadcast is done, finish up the low-level shutdown.
9500                Log.i(TAG, "Shutting down activity manager...");
9501                shutdown(10000);
9502                Log.i(TAG, "Shutdown complete, restarting!");
9503                Process.killProcess(Process.myPid());
9504                System.exit(10);
9505            }
9506        };
9507
9508        // First send the high-level shut down broadcast.
9509        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9510        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9511        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9512        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9513        mContext.sendOrderedBroadcastAsUser(intent,
9514                UserHandle.ALL, null, br, mHandler, 0, null, null);
9515        */
9516        br.onReceive(mContext, intent);
9517    }
9518
9519    private long getLowRamTimeSinceIdle(long now) {
9520        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9521    }
9522
9523    @Override
9524    public void performIdleMaintenance() {
9525        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9526                != PackageManager.PERMISSION_GRANTED) {
9527            throw new SecurityException("Requires permission "
9528                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9529        }
9530
9531        synchronized (this) {
9532            final long now = SystemClock.uptimeMillis();
9533            final long timeSinceLastIdle = now - mLastIdleTime;
9534            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9535            mLastIdleTime = now;
9536            mLowRamTimeSinceLastIdle = 0;
9537            if (mLowRamStartTime != 0) {
9538                mLowRamStartTime = now;
9539            }
9540
9541            StringBuilder sb = new StringBuilder(128);
9542            sb.append("Idle maintenance over ");
9543            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9544            sb.append(" low RAM for ");
9545            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9546            Slog.i(TAG, sb.toString());
9547
9548            // If at least 1/3 of our time since the last idle period has been spent
9549            // with RAM low, then we want to kill processes.
9550            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9551
9552            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9553                ProcessRecord proc = mLruProcesses.get(i);
9554                if (proc.notCachedSinceIdle) {
9555                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9556                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9557                        if (doKilling && proc.initialIdlePss != 0
9558                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9559                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9560                                    + " from " + proc.initialIdlePss + ")");
9561                        }
9562                    }
9563                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9564                    proc.notCachedSinceIdle = true;
9565                    proc.initialIdlePss = 0;
9566                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9567                            isSleeping(), now);
9568                }
9569            }
9570
9571            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9572            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9573        }
9574    }
9575
9576    private void retrieveSettings() {
9577        final ContentResolver resolver = mContext.getContentResolver();
9578        String debugApp = Settings.Global.getString(
9579            resolver, Settings.Global.DEBUG_APP);
9580        boolean waitForDebugger = Settings.Global.getInt(
9581            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9582        boolean alwaysFinishActivities = Settings.Global.getInt(
9583            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9584        boolean forceRtl = Settings.Global.getInt(
9585                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9586        // Transfer any global setting for forcing RTL layout, into a System Property
9587        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9588
9589        Configuration configuration = new Configuration();
9590        Settings.System.getConfiguration(resolver, configuration);
9591        if (forceRtl) {
9592            // This will take care of setting the correct layout direction flags
9593            configuration.setLayoutDirection(configuration.locale);
9594        }
9595
9596        synchronized (this) {
9597            mDebugApp = mOrigDebugApp = debugApp;
9598            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9599            mAlwaysFinishActivities = alwaysFinishActivities;
9600            // This happens before any activities are started, so we can
9601            // change mConfiguration in-place.
9602            updateConfigurationLocked(configuration, null, false, true);
9603            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9604        }
9605    }
9606
9607    public boolean testIsSystemReady() {
9608        // no need to synchronize(this) just to read & return the value
9609        return mSystemReady;
9610    }
9611
9612    private static File getCalledPreBootReceiversFile() {
9613        File dataDir = Environment.getDataDirectory();
9614        File systemDir = new File(dataDir, "system");
9615        File fname = new File(systemDir, "called_pre_boots.dat");
9616        return fname;
9617    }
9618
9619    static final int LAST_DONE_VERSION = 10000;
9620
9621    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9622        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9623        File file = getCalledPreBootReceiversFile();
9624        FileInputStream fis = null;
9625        try {
9626            fis = new FileInputStream(file);
9627            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9628            int fvers = dis.readInt();
9629            if (fvers == LAST_DONE_VERSION) {
9630                String vers = dis.readUTF();
9631                String codename = dis.readUTF();
9632                String build = dis.readUTF();
9633                if (android.os.Build.VERSION.RELEASE.equals(vers)
9634                        && android.os.Build.VERSION.CODENAME.equals(codename)
9635                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9636                    int num = dis.readInt();
9637                    while (num > 0) {
9638                        num--;
9639                        String pkg = dis.readUTF();
9640                        String cls = dis.readUTF();
9641                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9642                    }
9643                }
9644            }
9645        } catch (FileNotFoundException e) {
9646        } catch (IOException e) {
9647            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9648        } finally {
9649            if (fis != null) {
9650                try {
9651                    fis.close();
9652                } catch (IOException e) {
9653                }
9654            }
9655        }
9656        return lastDoneReceivers;
9657    }
9658
9659    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9660        File file = getCalledPreBootReceiversFile();
9661        FileOutputStream fos = null;
9662        DataOutputStream dos = null;
9663        try {
9664            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9665            fos = new FileOutputStream(file);
9666            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9667            dos.writeInt(LAST_DONE_VERSION);
9668            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9669            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9670            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9671            dos.writeInt(list.size());
9672            for (int i=0; i<list.size(); i++) {
9673                dos.writeUTF(list.get(i).getPackageName());
9674                dos.writeUTF(list.get(i).getClassName());
9675            }
9676        } catch (IOException e) {
9677            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9678            file.delete();
9679        } finally {
9680            FileUtils.sync(fos);
9681            if (dos != null) {
9682                try {
9683                    dos.close();
9684                } catch (IOException e) {
9685                    // TODO Auto-generated catch block
9686                    e.printStackTrace();
9687                }
9688            }
9689        }
9690    }
9691
9692    public void systemReady(final Runnable goingCallback) {
9693        synchronized(this) {
9694            if (mSystemReady) {
9695                if (goingCallback != null) goingCallback.run();
9696                return;
9697            }
9698
9699            if (mRecentTasks == null) {
9700                mRecentTasks = mTaskPersister.restoreTasksLocked();
9701                if (!mRecentTasks.isEmpty()) {
9702                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9703                }
9704                mTaskPersister.startPersisting();
9705            }
9706
9707            // Check to see if there are any update receivers to run.
9708            if (!mDidUpdate) {
9709                if (mWaitingUpdate) {
9710                    return;
9711                }
9712                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9713                List<ResolveInfo> ris = null;
9714                try {
9715                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9716                            intent, null, 0, 0);
9717                } catch (RemoteException e) {
9718                }
9719                if (ris != null) {
9720                    for (int i=ris.size()-1; i>=0; i--) {
9721                        if ((ris.get(i).activityInfo.applicationInfo.flags
9722                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9723                            ris.remove(i);
9724                        }
9725                    }
9726                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9727
9728                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9729
9730                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9731                    for (int i=0; i<ris.size(); i++) {
9732                        ActivityInfo ai = ris.get(i).activityInfo;
9733                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9734                        if (lastDoneReceivers.contains(comp)) {
9735                            // We already did the pre boot receiver for this app with the current
9736                            // platform version, so don't do it again...
9737                            ris.remove(i);
9738                            i--;
9739                            // ...however, do keep it as one that has been done, so we don't
9740                            // forget about it when rewriting the file of last done receivers.
9741                            doneReceivers.add(comp);
9742                        }
9743                    }
9744
9745                    final int[] users = getUsersLocked();
9746                    for (int i=0; i<ris.size(); i++) {
9747                        ActivityInfo ai = ris.get(i).activityInfo;
9748                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9749                        doneReceivers.add(comp);
9750                        intent.setComponent(comp);
9751                        for (int j=0; j<users.length; j++) {
9752                            IIntentReceiver finisher = null;
9753                            if (i == ris.size()-1 && j == users.length-1) {
9754                                finisher = new IIntentReceiver.Stub() {
9755                                    public void performReceive(Intent intent, int resultCode,
9756                                            String data, Bundle extras, boolean ordered,
9757                                            boolean sticky, int sendingUser) {
9758                                        // The raw IIntentReceiver interface is called
9759                                        // with the AM lock held, so redispatch to
9760                                        // execute our code without the lock.
9761                                        mHandler.post(new Runnable() {
9762                                            public void run() {
9763                                                synchronized (ActivityManagerService.this) {
9764                                                    mDidUpdate = true;
9765                                                }
9766                                                writeLastDonePreBootReceivers(doneReceivers);
9767                                                showBootMessage(mContext.getText(
9768                                                        R.string.android_upgrading_complete),
9769                                                        false);
9770                                                systemReady(goingCallback);
9771                                            }
9772                                        });
9773                                    }
9774                                };
9775                            }
9776                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9777                                    + " for user " + users[j]);
9778                            broadcastIntentLocked(null, null, intent, null, finisher,
9779                                    0, null, null, null, AppOpsManager.OP_NONE,
9780                                    true, false, MY_PID, Process.SYSTEM_UID,
9781                                    users[j]);
9782                            if (finisher != null) {
9783                                mWaitingUpdate = true;
9784                            }
9785                        }
9786                    }
9787                }
9788                if (mWaitingUpdate) {
9789                    return;
9790                }
9791                mDidUpdate = true;
9792            }
9793
9794            mAppOpsService.systemReady();
9795            mUsageStatsService.systemReady();
9796            mSystemReady = true;
9797        }
9798
9799        ArrayList<ProcessRecord> procsToKill = null;
9800        synchronized(mPidsSelfLocked) {
9801            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9802                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9803                if (!isAllowedWhileBooting(proc.info)){
9804                    if (procsToKill == null) {
9805                        procsToKill = new ArrayList<ProcessRecord>();
9806                    }
9807                    procsToKill.add(proc);
9808                }
9809            }
9810        }
9811
9812        synchronized(this) {
9813            if (procsToKill != null) {
9814                for (int i=procsToKill.size()-1; i>=0; i--) {
9815                    ProcessRecord proc = procsToKill.get(i);
9816                    Slog.i(TAG, "Removing system update proc: " + proc);
9817                    removeProcessLocked(proc, true, false, "system update done");
9818                }
9819            }
9820
9821            // Now that we have cleaned up any update processes, we
9822            // are ready to start launching real processes and know that
9823            // we won't trample on them any more.
9824            mProcessesReady = true;
9825        }
9826
9827        Slog.i(TAG, "System now ready");
9828        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9829            SystemClock.uptimeMillis());
9830
9831        synchronized(this) {
9832            // Make sure we have no pre-ready processes sitting around.
9833
9834            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9835                ResolveInfo ri = mContext.getPackageManager()
9836                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9837                                STOCK_PM_FLAGS);
9838                CharSequence errorMsg = null;
9839                if (ri != null) {
9840                    ActivityInfo ai = ri.activityInfo;
9841                    ApplicationInfo app = ai.applicationInfo;
9842                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9843                        mTopAction = Intent.ACTION_FACTORY_TEST;
9844                        mTopData = null;
9845                        mTopComponent = new ComponentName(app.packageName,
9846                                ai.name);
9847                    } else {
9848                        errorMsg = mContext.getResources().getText(
9849                                com.android.internal.R.string.factorytest_not_system);
9850                    }
9851                } else {
9852                    errorMsg = mContext.getResources().getText(
9853                            com.android.internal.R.string.factorytest_no_action);
9854                }
9855                if (errorMsg != null) {
9856                    mTopAction = null;
9857                    mTopData = null;
9858                    mTopComponent = null;
9859                    Message msg = Message.obtain();
9860                    msg.what = SHOW_FACTORY_ERROR_MSG;
9861                    msg.getData().putCharSequence("msg", errorMsg);
9862                    mHandler.sendMessage(msg);
9863                }
9864            }
9865        }
9866
9867        retrieveSettings();
9868
9869        synchronized (this) {
9870            readGrantedUriPermissionsLocked();
9871        }
9872
9873        if (goingCallback != null) goingCallback.run();
9874
9875        mSystemServiceManager.startUser(mCurrentUserId);
9876
9877        synchronized (this) {
9878            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9879                try {
9880                    List apps = AppGlobals.getPackageManager().
9881                        getPersistentApplications(STOCK_PM_FLAGS);
9882                    if (apps != null) {
9883                        int N = apps.size();
9884                        int i;
9885                        for (i=0; i<N; i++) {
9886                            ApplicationInfo info
9887                                = (ApplicationInfo)apps.get(i);
9888                            if (info != null &&
9889                                    !info.packageName.equals("android")) {
9890                                addAppLocked(info, false, null /* ABI override */);
9891                            }
9892                        }
9893                    }
9894                } catch (RemoteException ex) {
9895                    // pm is in same process, this will never happen.
9896                }
9897            }
9898
9899            // Start up initial activity.
9900            mBooting = true;
9901
9902            try {
9903                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9904                    Message msg = Message.obtain();
9905                    msg.what = SHOW_UID_ERROR_MSG;
9906                    mHandler.sendMessage(msg);
9907                }
9908            } catch (RemoteException e) {
9909            }
9910
9911            long ident = Binder.clearCallingIdentity();
9912            try {
9913                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9914                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9915                        | Intent.FLAG_RECEIVER_FOREGROUND);
9916                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9917                broadcastIntentLocked(null, null, intent,
9918                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9919                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9920                intent = new Intent(Intent.ACTION_USER_STARTING);
9921                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9922                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9923                broadcastIntentLocked(null, null, intent,
9924                        null, new IIntentReceiver.Stub() {
9925                            @Override
9926                            public void performReceive(Intent intent, int resultCode, String data,
9927                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9928                                    throws RemoteException {
9929                            }
9930                        }, 0, null, null,
9931                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9932                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9933            } catch (Throwable t) {
9934                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9935            } finally {
9936                Binder.restoreCallingIdentity(ident);
9937            }
9938            mStackSupervisor.resumeTopActivitiesLocked();
9939            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9940        }
9941    }
9942
9943    private boolean makeAppCrashingLocked(ProcessRecord app,
9944            String shortMsg, String longMsg, String stackTrace) {
9945        app.crashing = true;
9946        app.crashingReport = generateProcessError(app,
9947                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9948        startAppProblemLocked(app);
9949        app.stopFreezingAllLocked();
9950        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9951    }
9952
9953    private void makeAppNotRespondingLocked(ProcessRecord app,
9954            String activity, String shortMsg, String longMsg) {
9955        app.notResponding = true;
9956        app.notRespondingReport = generateProcessError(app,
9957                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9958                activity, shortMsg, longMsg, null);
9959        startAppProblemLocked(app);
9960        app.stopFreezingAllLocked();
9961    }
9962
9963    /**
9964     * Generate a process error record, suitable for attachment to a ProcessRecord.
9965     *
9966     * @param app The ProcessRecord in which the error occurred.
9967     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9968     *                      ActivityManager.AppErrorStateInfo
9969     * @param activity The activity associated with the crash, if known.
9970     * @param shortMsg Short message describing the crash.
9971     * @param longMsg Long message describing the crash.
9972     * @param stackTrace Full crash stack trace, may be null.
9973     *
9974     * @return Returns a fully-formed AppErrorStateInfo record.
9975     */
9976    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9977            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9978        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9979
9980        report.condition = condition;
9981        report.processName = app.processName;
9982        report.pid = app.pid;
9983        report.uid = app.info.uid;
9984        report.tag = activity;
9985        report.shortMsg = shortMsg;
9986        report.longMsg = longMsg;
9987        report.stackTrace = stackTrace;
9988
9989        return report;
9990    }
9991
9992    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9993        synchronized (this) {
9994            app.crashing = false;
9995            app.crashingReport = null;
9996            app.notResponding = false;
9997            app.notRespondingReport = null;
9998            if (app.anrDialog == fromDialog) {
9999                app.anrDialog = null;
10000            }
10001            if (app.waitDialog == fromDialog) {
10002                app.waitDialog = null;
10003            }
10004            if (app.pid > 0 && app.pid != MY_PID) {
10005                handleAppCrashLocked(app, null, null, null);
10006                killUnneededProcessLocked(app, "user request after error");
10007            }
10008        }
10009    }
10010
10011    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10012            String stackTrace) {
10013        long now = SystemClock.uptimeMillis();
10014
10015        Long crashTime;
10016        if (!app.isolated) {
10017            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10018        } else {
10019            crashTime = null;
10020        }
10021        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10022            // This process loses!
10023            Slog.w(TAG, "Process " + app.info.processName
10024                    + " has crashed too many times: killing!");
10025            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10026                    app.userId, app.info.processName, app.uid);
10027            mStackSupervisor.handleAppCrashLocked(app);
10028            if (!app.persistent) {
10029                // We don't want to start this process again until the user
10030                // explicitly does so...  but for persistent process, we really
10031                // need to keep it running.  If a persistent process is actually
10032                // repeatedly crashing, then badness for everyone.
10033                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10034                        app.info.processName);
10035                if (!app.isolated) {
10036                    // XXX We don't have a way to mark isolated processes
10037                    // as bad, since they don't have a peristent identity.
10038                    mBadProcesses.put(app.info.processName, app.uid,
10039                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10040                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10041                }
10042                app.bad = true;
10043                app.removed = true;
10044                // Don't let services in this process be restarted and potentially
10045                // annoy the user repeatedly.  Unless it is persistent, since those
10046                // processes run critical code.
10047                removeProcessLocked(app, false, false, "crash");
10048                mStackSupervisor.resumeTopActivitiesLocked();
10049                return false;
10050            }
10051            mStackSupervisor.resumeTopActivitiesLocked();
10052        } else {
10053            mStackSupervisor.finishTopRunningActivityLocked(app);
10054        }
10055
10056        // Bump up the crash count of any services currently running in the proc.
10057        for (int i=app.services.size()-1; i>=0; i--) {
10058            // Any services running in the application need to be placed
10059            // back in the pending list.
10060            ServiceRecord sr = app.services.valueAt(i);
10061            sr.crashCount++;
10062        }
10063
10064        // If the crashing process is what we consider to be the "home process" and it has been
10065        // replaced by a third-party app, clear the package preferred activities from packages
10066        // with a home activity running in the process to prevent a repeatedly crashing app
10067        // from blocking the user to manually clear the list.
10068        final ArrayList<ActivityRecord> activities = app.activities;
10069        if (app == mHomeProcess && activities.size() > 0
10070                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10071            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10072                final ActivityRecord r = activities.get(activityNdx);
10073                if (r.isHomeActivity()) {
10074                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10075                    try {
10076                        ActivityThread.getPackageManager()
10077                                .clearPackagePreferredActivities(r.packageName);
10078                    } catch (RemoteException c) {
10079                        // pm is in same process, this will never happen.
10080                    }
10081                }
10082            }
10083        }
10084
10085        if (!app.isolated) {
10086            // XXX Can't keep track of crash times for isolated processes,
10087            // because they don't have a perisistent identity.
10088            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10089        }
10090
10091        return true;
10092    }
10093
10094    void startAppProblemLocked(ProcessRecord app) {
10095        if (app.userId == mCurrentUserId) {
10096            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10097                    mContext, app.info.packageName, app.info.flags);
10098        } else {
10099            // If this app is not running under the current user, then we
10100            // can't give it a report button because that would require
10101            // launching the report UI under a different user.
10102            app.errorReportReceiver = null;
10103        }
10104        skipCurrentReceiverLocked(app);
10105    }
10106
10107    void skipCurrentReceiverLocked(ProcessRecord app) {
10108        for (BroadcastQueue queue : mBroadcastQueues) {
10109            queue.skipCurrentReceiverLocked(app);
10110        }
10111    }
10112
10113    /**
10114     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10115     * The application process will exit immediately after this call returns.
10116     * @param app object of the crashing app, null for the system server
10117     * @param crashInfo describing the exception
10118     */
10119    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10120        ProcessRecord r = findAppProcess(app, "Crash");
10121        final String processName = app == null ? "system_server"
10122                : (r == null ? "unknown" : r.processName);
10123
10124        handleApplicationCrashInner("crash", r, processName, crashInfo);
10125    }
10126
10127    /* Native crash reporting uses this inner version because it needs to be somewhat
10128     * decoupled from the AM-managed cleanup lifecycle
10129     */
10130    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10131            ApplicationErrorReport.CrashInfo crashInfo) {
10132        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10133                UserHandle.getUserId(Binder.getCallingUid()), processName,
10134                r == null ? -1 : r.info.flags,
10135                crashInfo.exceptionClassName,
10136                crashInfo.exceptionMessage,
10137                crashInfo.throwFileName,
10138                crashInfo.throwLineNumber);
10139
10140        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10141
10142        crashApplication(r, crashInfo);
10143    }
10144
10145    public void handleApplicationStrictModeViolation(
10146            IBinder app,
10147            int violationMask,
10148            StrictMode.ViolationInfo info) {
10149        ProcessRecord r = findAppProcess(app, "StrictMode");
10150        if (r == null) {
10151            return;
10152        }
10153
10154        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10155            Integer stackFingerprint = info.hashCode();
10156            boolean logIt = true;
10157            synchronized (mAlreadyLoggedViolatedStacks) {
10158                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10159                    logIt = false;
10160                    // TODO: sub-sample into EventLog for these, with
10161                    // the info.durationMillis?  Then we'd get
10162                    // the relative pain numbers, without logging all
10163                    // the stack traces repeatedly.  We'd want to do
10164                    // likewise in the client code, which also does
10165                    // dup suppression, before the Binder call.
10166                } else {
10167                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10168                        mAlreadyLoggedViolatedStacks.clear();
10169                    }
10170                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10171                }
10172            }
10173            if (logIt) {
10174                logStrictModeViolationToDropBox(r, info);
10175            }
10176        }
10177
10178        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10179            AppErrorResult result = new AppErrorResult();
10180            synchronized (this) {
10181                final long origId = Binder.clearCallingIdentity();
10182
10183                Message msg = Message.obtain();
10184                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10185                HashMap<String, Object> data = new HashMap<String, Object>();
10186                data.put("result", result);
10187                data.put("app", r);
10188                data.put("violationMask", violationMask);
10189                data.put("info", info);
10190                msg.obj = data;
10191                mHandler.sendMessage(msg);
10192
10193                Binder.restoreCallingIdentity(origId);
10194            }
10195            int res = result.get();
10196            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10197        }
10198    }
10199
10200    // Depending on the policy in effect, there could be a bunch of
10201    // these in quick succession so we try to batch these together to
10202    // minimize disk writes, number of dropbox entries, and maximize
10203    // compression, by having more fewer, larger records.
10204    private void logStrictModeViolationToDropBox(
10205            ProcessRecord process,
10206            StrictMode.ViolationInfo info) {
10207        if (info == null) {
10208            return;
10209        }
10210        final boolean isSystemApp = process == null ||
10211                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10212                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10213        final String processName = process == null ? "unknown" : process.processName;
10214        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10215        final DropBoxManager dbox = (DropBoxManager)
10216                mContext.getSystemService(Context.DROPBOX_SERVICE);
10217
10218        // Exit early if the dropbox isn't configured to accept this report type.
10219        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10220
10221        boolean bufferWasEmpty;
10222        boolean needsFlush;
10223        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10224        synchronized (sb) {
10225            bufferWasEmpty = sb.length() == 0;
10226            appendDropBoxProcessHeaders(process, processName, sb);
10227            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10228            sb.append("System-App: ").append(isSystemApp).append("\n");
10229            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10230            if (info.violationNumThisLoop != 0) {
10231                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10232            }
10233            if (info.numAnimationsRunning != 0) {
10234                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10235            }
10236            if (info.broadcastIntentAction != null) {
10237                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10238            }
10239            if (info.durationMillis != -1) {
10240                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10241            }
10242            if (info.numInstances != -1) {
10243                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10244            }
10245            if (info.tags != null) {
10246                for (String tag : info.tags) {
10247                    sb.append("Span-Tag: ").append(tag).append("\n");
10248                }
10249            }
10250            sb.append("\n");
10251            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10252                sb.append(info.crashInfo.stackTrace);
10253            }
10254            sb.append("\n");
10255
10256            // Only buffer up to ~64k.  Various logging bits truncate
10257            // things at 128k.
10258            needsFlush = (sb.length() > 64 * 1024);
10259        }
10260
10261        // Flush immediately if the buffer's grown too large, or this
10262        // is a non-system app.  Non-system apps are isolated with a
10263        // different tag & policy and not batched.
10264        //
10265        // Batching is useful during internal testing with
10266        // StrictMode settings turned up high.  Without batching,
10267        // thousands of separate files could be created on boot.
10268        if (!isSystemApp || needsFlush) {
10269            new Thread("Error dump: " + dropboxTag) {
10270                @Override
10271                public void run() {
10272                    String report;
10273                    synchronized (sb) {
10274                        report = sb.toString();
10275                        sb.delete(0, sb.length());
10276                        sb.trimToSize();
10277                    }
10278                    if (report.length() != 0) {
10279                        dbox.addText(dropboxTag, report);
10280                    }
10281                }
10282            }.start();
10283            return;
10284        }
10285
10286        // System app batching:
10287        if (!bufferWasEmpty) {
10288            // An existing dropbox-writing thread is outstanding, so
10289            // we don't need to start it up.  The existing thread will
10290            // catch the buffer appends we just did.
10291            return;
10292        }
10293
10294        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10295        // (After this point, we shouldn't access AMS internal data structures.)
10296        new Thread("Error dump: " + dropboxTag) {
10297            @Override
10298            public void run() {
10299                // 5 second sleep to let stacks arrive and be batched together
10300                try {
10301                    Thread.sleep(5000);  // 5 seconds
10302                } catch (InterruptedException e) {}
10303
10304                String errorReport;
10305                synchronized (mStrictModeBuffer) {
10306                    errorReport = mStrictModeBuffer.toString();
10307                    if (errorReport.length() == 0) {
10308                        return;
10309                    }
10310                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10311                    mStrictModeBuffer.trimToSize();
10312                }
10313                dbox.addText(dropboxTag, errorReport);
10314            }
10315        }.start();
10316    }
10317
10318    /**
10319     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10320     * @param app object of the crashing app, null for the system server
10321     * @param tag reported by the caller
10322     * @param crashInfo describing the context of the error
10323     * @return true if the process should exit immediately (WTF is fatal)
10324     */
10325    public boolean handleApplicationWtf(IBinder app, String tag,
10326            ApplicationErrorReport.CrashInfo crashInfo) {
10327        ProcessRecord r = findAppProcess(app, "WTF");
10328        final String processName = app == null ? "system_server"
10329                : (r == null ? "unknown" : r.processName);
10330
10331        EventLog.writeEvent(EventLogTags.AM_WTF,
10332                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10333                processName,
10334                r == null ? -1 : r.info.flags,
10335                tag, crashInfo.exceptionMessage);
10336
10337        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10338
10339        if (r != null && r.pid != Process.myPid() &&
10340                Settings.Global.getInt(mContext.getContentResolver(),
10341                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10342            crashApplication(r, crashInfo);
10343            return true;
10344        } else {
10345            return false;
10346        }
10347    }
10348
10349    /**
10350     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10351     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10352     */
10353    private ProcessRecord findAppProcess(IBinder app, String reason) {
10354        if (app == null) {
10355            return null;
10356        }
10357
10358        synchronized (this) {
10359            final int NP = mProcessNames.getMap().size();
10360            for (int ip=0; ip<NP; ip++) {
10361                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10362                final int NA = apps.size();
10363                for (int ia=0; ia<NA; ia++) {
10364                    ProcessRecord p = apps.valueAt(ia);
10365                    if (p.thread != null && p.thread.asBinder() == app) {
10366                        return p;
10367                    }
10368                }
10369            }
10370
10371            Slog.w(TAG, "Can't find mystery application for " + reason
10372                    + " from pid=" + Binder.getCallingPid()
10373                    + " uid=" + Binder.getCallingUid() + ": " + app);
10374            return null;
10375        }
10376    }
10377
10378    /**
10379     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10380     * to append various headers to the dropbox log text.
10381     */
10382    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10383            StringBuilder sb) {
10384        // Watchdog thread ends up invoking this function (with
10385        // a null ProcessRecord) to add the stack file to dropbox.
10386        // Do not acquire a lock on this (am) in such cases, as it
10387        // could cause a potential deadlock, if and when watchdog
10388        // is invoked due to unavailability of lock on am and it
10389        // would prevent watchdog from killing system_server.
10390        if (process == null) {
10391            sb.append("Process: ").append(processName).append("\n");
10392            return;
10393        }
10394        // Note: ProcessRecord 'process' is guarded by the service
10395        // instance.  (notably process.pkgList, which could otherwise change
10396        // concurrently during execution of this method)
10397        synchronized (this) {
10398            sb.append("Process: ").append(processName).append("\n");
10399            int flags = process.info.flags;
10400            IPackageManager pm = AppGlobals.getPackageManager();
10401            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10402            for (int ip=0; ip<process.pkgList.size(); ip++) {
10403                String pkg = process.pkgList.keyAt(ip);
10404                sb.append("Package: ").append(pkg);
10405                try {
10406                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10407                    if (pi != null) {
10408                        sb.append(" v").append(pi.versionCode);
10409                        if (pi.versionName != null) {
10410                            sb.append(" (").append(pi.versionName).append(")");
10411                        }
10412                    }
10413                } catch (RemoteException e) {
10414                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10415                }
10416                sb.append("\n");
10417            }
10418        }
10419    }
10420
10421    private static String processClass(ProcessRecord process) {
10422        if (process == null || process.pid == MY_PID) {
10423            return "system_server";
10424        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10425            return "system_app";
10426        } else {
10427            return "data_app";
10428        }
10429    }
10430
10431    /**
10432     * Write a description of an error (crash, WTF, ANR) to the drop box.
10433     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10434     * @param process which caused the error, null means the system server
10435     * @param activity which triggered the error, null if unknown
10436     * @param parent activity related to the error, null if unknown
10437     * @param subject line related to the error, null if absent
10438     * @param report in long form describing the error, null if absent
10439     * @param logFile to include in the report, null if none
10440     * @param crashInfo giving an application stack trace, null if absent
10441     */
10442    public void addErrorToDropBox(String eventType,
10443            ProcessRecord process, String processName, ActivityRecord activity,
10444            ActivityRecord parent, String subject,
10445            final String report, final File logFile,
10446            final ApplicationErrorReport.CrashInfo crashInfo) {
10447        // NOTE -- this must never acquire the ActivityManagerService lock,
10448        // otherwise the watchdog may be prevented from resetting the system.
10449
10450        final String dropboxTag = processClass(process) + "_" + eventType;
10451        final DropBoxManager dbox = (DropBoxManager)
10452                mContext.getSystemService(Context.DROPBOX_SERVICE);
10453
10454        // Exit early if the dropbox isn't configured to accept this report type.
10455        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10456
10457        final StringBuilder sb = new StringBuilder(1024);
10458        appendDropBoxProcessHeaders(process, processName, sb);
10459        if (activity != null) {
10460            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10461        }
10462        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10463            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10464        }
10465        if (parent != null && parent != activity) {
10466            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10467        }
10468        if (subject != null) {
10469            sb.append("Subject: ").append(subject).append("\n");
10470        }
10471        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10472        if (Debug.isDebuggerConnected()) {
10473            sb.append("Debugger: Connected\n");
10474        }
10475        sb.append("\n");
10476
10477        // Do the rest in a worker thread to avoid blocking the caller on I/O
10478        // (After this point, we shouldn't access AMS internal data structures.)
10479        Thread worker = new Thread("Error dump: " + dropboxTag) {
10480            @Override
10481            public void run() {
10482                if (report != null) {
10483                    sb.append(report);
10484                }
10485                if (logFile != null) {
10486                    try {
10487                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10488                                    "\n\n[[TRUNCATED]]"));
10489                    } catch (IOException e) {
10490                        Slog.e(TAG, "Error reading " + logFile, e);
10491                    }
10492                }
10493                if (crashInfo != null && crashInfo.stackTrace != null) {
10494                    sb.append(crashInfo.stackTrace);
10495                }
10496
10497                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10498                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10499                if (lines > 0) {
10500                    sb.append("\n");
10501
10502                    // Merge several logcat streams, and take the last N lines
10503                    InputStreamReader input = null;
10504                    try {
10505                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10506                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10507                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10508
10509                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10510                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10511                        input = new InputStreamReader(logcat.getInputStream());
10512
10513                        int num;
10514                        char[] buf = new char[8192];
10515                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10516                    } catch (IOException e) {
10517                        Slog.e(TAG, "Error running logcat", e);
10518                    } finally {
10519                        if (input != null) try { input.close(); } catch (IOException e) {}
10520                    }
10521                }
10522
10523                dbox.addText(dropboxTag, sb.toString());
10524            }
10525        };
10526
10527        if (process == null) {
10528            // If process is null, we are being called from some internal code
10529            // and may be about to die -- run this synchronously.
10530            worker.run();
10531        } else {
10532            worker.start();
10533        }
10534    }
10535
10536    /**
10537     * Bring up the "unexpected error" dialog box for a crashing app.
10538     * Deal with edge cases (intercepts from instrumented applications,
10539     * ActivityController, error intent receivers, that sort of thing).
10540     * @param r the application crashing
10541     * @param crashInfo describing the failure
10542     */
10543    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10544        long timeMillis = System.currentTimeMillis();
10545        String shortMsg = crashInfo.exceptionClassName;
10546        String longMsg = crashInfo.exceptionMessage;
10547        String stackTrace = crashInfo.stackTrace;
10548        if (shortMsg != null && longMsg != null) {
10549            longMsg = shortMsg + ": " + longMsg;
10550        } else if (shortMsg != null) {
10551            longMsg = shortMsg;
10552        }
10553
10554        AppErrorResult result = new AppErrorResult();
10555        synchronized (this) {
10556            if (mController != null) {
10557                try {
10558                    String name = r != null ? r.processName : null;
10559                    int pid = r != null ? r.pid : Binder.getCallingPid();
10560                    if (!mController.appCrashed(name, pid,
10561                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10562                        Slog.w(TAG, "Force-killing crashed app " + name
10563                                + " at watcher's request");
10564                        Process.killProcess(pid);
10565                        return;
10566                    }
10567                } catch (RemoteException e) {
10568                    mController = null;
10569                    Watchdog.getInstance().setActivityController(null);
10570                }
10571            }
10572
10573            final long origId = Binder.clearCallingIdentity();
10574
10575            // If this process is running instrumentation, finish it.
10576            if (r != null && r.instrumentationClass != null) {
10577                Slog.w(TAG, "Error in app " + r.processName
10578                      + " running instrumentation " + r.instrumentationClass + ":");
10579                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10580                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10581                Bundle info = new Bundle();
10582                info.putString("shortMsg", shortMsg);
10583                info.putString("longMsg", longMsg);
10584                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10585                Binder.restoreCallingIdentity(origId);
10586                return;
10587            }
10588
10589            // If we can't identify the process or it's already exceeded its crash quota,
10590            // quit right away without showing a crash dialog.
10591            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10592                Binder.restoreCallingIdentity(origId);
10593                return;
10594            }
10595
10596            Message msg = Message.obtain();
10597            msg.what = SHOW_ERROR_MSG;
10598            HashMap data = new HashMap();
10599            data.put("result", result);
10600            data.put("app", r);
10601            msg.obj = data;
10602            mHandler.sendMessage(msg);
10603
10604            Binder.restoreCallingIdentity(origId);
10605        }
10606
10607        int res = result.get();
10608
10609        Intent appErrorIntent = null;
10610        synchronized (this) {
10611            if (r != null && !r.isolated) {
10612                // XXX Can't keep track of crash time for isolated processes,
10613                // since they don't have a persistent identity.
10614                mProcessCrashTimes.put(r.info.processName, r.uid,
10615                        SystemClock.uptimeMillis());
10616            }
10617            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10618                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10619            }
10620        }
10621
10622        if (appErrorIntent != null) {
10623            try {
10624                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10625            } catch (ActivityNotFoundException e) {
10626                Slog.w(TAG, "bug report receiver dissappeared", e);
10627            }
10628        }
10629    }
10630
10631    Intent createAppErrorIntentLocked(ProcessRecord r,
10632            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10633        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10634        if (report == null) {
10635            return null;
10636        }
10637        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10638        result.setComponent(r.errorReportReceiver);
10639        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10640        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10641        return result;
10642    }
10643
10644    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10645            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10646        if (r.errorReportReceiver == null) {
10647            return null;
10648        }
10649
10650        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10651            return null;
10652        }
10653
10654        ApplicationErrorReport report = new ApplicationErrorReport();
10655        report.packageName = r.info.packageName;
10656        report.installerPackageName = r.errorReportReceiver.getPackageName();
10657        report.processName = r.processName;
10658        report.time = timeMillis;
10659        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10660
10661        if (r.crashing || r.forceCrashReport) {
10662            report.type = ApplicationErrorReport.TYPE_CRASH;
10663            report.crashInfo = crashInfo;
10664        } else if (r.notResponding) {
10665            report.type = ApplicationErrorReport.TYPE_ANR;
10666            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10667
10668            report.anrInfo.activity = r.notRespondingReport.tag;
10669            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10670            report.anrInfo.info = r.notRespondingReport.longMsg;
10671        }
10672
10673        return report;
10674    }
10675
10676    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10677        enforceNotIsolatedCaller("getProcessesInErrorState");
10678        // assume our apps are happy - lazy create the list
10679        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10680
10681        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10682                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10683        int userId = UserHandle.getUserId(Binder.getCallingUid());
10684
10685        synchronized (this) {
10686
10687            // iterate across all processes
10688            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10689                ProcessRecord app = mLruProcesses.get(i);
10690                if (!allUsers && app.userId != userId) {
10691                    continue;
10692                }
10693                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10694                    // This one's in trouble, so we'll generate a report for it
10695                    // crashes are higher priority (in case there's a crash *and* an anr)
10696                    ActivityManager.ProcessErrorStateInfo report = null;
10697                    if (app.crashing) {
10698                        report = app.crashingReport;
10699                    } else if (app.notResponding) {
10700                        report = app.notRespondingReport;
10701                    }
10702
10703                    if (report != null) {
10704                        if (errList == null) {
10705                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10706                        }
10707                        errList.add(report);
10708                    } else {
10709                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10710                                " crashing = " + app.crashing +
10711                                " notResponding = " + app.notResponding);
10712                    }
10713                }
10714            }
10715        }
10716
10717        return errList;
10718    }
10719
10720    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10721        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10722            if (currApp != null) {
10723                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10724            }
10725            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10726        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10727            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10728        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10729            if (currApp != null) {
10730                currApp.lru = 0;
10731            }
10732            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10733        } else if (adj >= ProcessList.SERVICE_ADJ) {
10734            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10735        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10736            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10737        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10738            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10739        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10740            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10741        } else {
10742            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10743        }
10744    }
10745
10746    private void fillInProcMemInfo(ProcessRecord app,
10747            ActivityManager.RunningAppProcessInfo outInfo) {
10748        outInfo.pid = app.pid;
10749        outInfo.uid = app.info.uid;
10750        if (mHeavyWeightProcess == app) {
10751            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10752        }
10753        if (app.persistent) {
10754            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10755        }
10756        if (app.activities.size() > 0) {
10757            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10758        }
10759        outInfo.lastTrimLevel = app.trimMemoryLevel;
10760        int adj = app.curAdj;
10761        outInfo.importance = oomAdjToImportance(adj, outInfo);
10762        outInfo.importanceReasonCode = app.adjTypeCode;
10763        outInfo.processState = app.curProcState;
10764    }
10765
10766    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10767        enforceNotIsolatedCaller("getRunningAppProcesses");
10768        // Lazy instantiation of list
10769        List<ActivityManager.RunningAppProcessInfo> runList = null;
10770        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10771                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10772        int userId = UserHandle.getUserId(Binder.getCallingUid());
10773        synchronized (this) {
10774            // Iterate across all processes
10775            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10776                ProcessRecord app = mLruProcesses.get(i);
10777                if (!allUsers && app.userId != userId) {
10778                    continue;
10779                }
10780                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10781                    // Generate process state info for running application
10782                    ActivityManager.RunningAppProcessInfo currApp =
10783                        new ActivityManager.RunningAppProcessInfo(app.processName,
10784                                app.pid, app.getPackageList());
10785                    fillInProcMemInfo(app, currApp);
10786                    if (app.adjSource instanceof ProcessRecord) {
10787                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10788                        currApp.importanceReasonImportance = oomAdjToImportance(
10789                                app.adjSourceOom, null);
10790                    } else if (app.adjSource instanceof ActivityRecord) {
10791                        ActivityRecord r = (ActivityRecord)app.adjSource;
10792                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10793                    }
10794                    if (app.adjTarget instanceof ComponentName) {
10795                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10796                    }
10797                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10798                    //        + " lru=" + currApp.lru);
10799                    if (runList == null) {
10800                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10801                    }
10802                    runList.add(currApp);
10803                }
10804            }
10805        }
10806        return runList;
10807    }
10808
10809    public List<ApplicationInfo> getRunningExternalApplications() {
10810        enforceNotIsolatedCaller("getRunningExternalApplications");
10811        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10812        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10813        if (runningApps != null && runningApps.size() > 0) {
10814            Set<String> extList = new HashSet<String>();
10815            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10816                if (app.pkgList != null) {
10817                    for (String pkg : app.pkgList) {
10818                        extList.add(pkg);
10819                    }
10820                }
10821            }
10822            IPackageManager pm = AppGlobals.getPackageManager();
10823            for (String pkg : extList) {
10824                try {
10825                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10826                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10827                        retList.add(info);
10828                    }
10829                } catch (RemoteException e) {
10830                }
10831            }
10832        }
10833        return retList;
10834    }
10835
10836    @Override
10837    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10838        enforceNotIsolatedCaller("getMyMemoryState");
10839        synchronized (this) {
10840            ProcessRecord proc;
10841            synchronized (mPidsSelfLocked) {
10842                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10843            }
10844            fillInProcMemInfo(proc, outInfo);
10845        }
10846    }
10847
10848    @Override
10849    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10850        if (checkCallingPermission(android.Manifest.permission.DUMP)
10851                != PackageManager.PERMISSION_GRANTED) {
10852            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10853                    + Binder.getCallingPid()
10854                    + ", uid=" + Binder.getCallingUid()
10855                    + " without permission "
10856                    + android.Manifest.permission.DUMP);
10857            return;
10858        }
10859
10860        boolean dumpAll = false;
10861        boolean dumpClient = false;
10862        String dumpPackage = null;
10863
10864        int opti = 0;
10865        while (opti < args.length) {
10866            String opt = args[opti];
10867            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10868                break;
10869            }
10870            opti++;
10871            if ("-a".equals(opt)) {
10872                dumpAll = true;
10873            } else if ("-c".equals(opt)) {
10874                dumpClient = true;
10875            } else if ("-h".equals(opt)) {
10876                pw.println("Activity manager dump options:");
10877                pw.println("  [-a] [-c] [-h] [cmd] ...");
10878                pw.println("  cmd may be one of:");
10879                pw.println("    a[ctivities]: activity stack state");
10880                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10881                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10882                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10883                pw.println("    o[om]: out of memory management");
10884                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10885                pw.println("    provider [COMP_SPEC]: provider client-side state");
10886                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10887                pw.println("    service [COMP_SPEC]: service client-side state");
10888                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10889                pw.println("    all: dump all activities");
10890                pw.println("    top: dump the top activity");
10891                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10892                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10893                pw.println("    a partial substring in a component name, a");
10894                pw.println("    hex object identifier.");
10895                pw.println("  -a: include all available server state.");
10896                pw.println("  -c: include client state.");
10897                return;
10898            } else {
10899                pw.println("Unknown argument: " + opt + "; use -h for help");
10900            }
10901        }
10902
10903        long origId = Binder.clearCallingIdentity();
10904        boolean more = false;
10905        // Is the caller requesting to dump a particular piece of data?
10906        if (opti < args.length) {
10907            String cmd = args[opti];
10908            opti++;
10909            if ("activities".equals(cmd) || "a".equals(cmd)) {
10910                synchronized (this) {
10911                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10912                }
10913            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10914                String[] newArgs;
10915                String name;
10916                if (opti >= args.length) {
10917                    name = null;
10918                    newArgs = EMPTY_STRING_ARRAY;
10919                } else {
10920                    name = args[opti];
10921                    opti++;
10922                    newArgs = new String[args.length - opti];
10923                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10924                            args.length - opti);
10925                }
10926                synchronized (this) {
10927                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10928                }
10929            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10930                String[] newArgs;
10931                String name;
10932                if (opti >= args.length) {
10933                    name = null;
10934                    newArgs = EMPTY_STRING_ARRAY;
10935                } else {
10936                    name = args[opti];
10937                    opti++;
10938                    newArgs = new String[args.length - opti];
10939                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10940                            args.length - opti);
10941                }
10942                synchronized (this) {
10943                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10944                }
10945            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10946                String[] newArgs;
10947                String name;
10948                if (opti >= args.length) {
10949                    name = null;
10950                    newArgs = EMPTY_STRING_ARRAY;
10951                } else {
10952                    name = args[opti];
10953                    opti++;
10954                    newArgs = new String[args.length - opti];
10955                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10956                            args.length - opti);
10957                }
10958                synchronized (this) {
10959                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10960                }
10961            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10962                synchronized (this) {
10963                    dumpOomLocked(fd, pw, args, opti, true);
10964                }
10965            } else if ("provider".equals(cmd)) {
10966                String[] newArgs;
10967                String name;
10968                if (opti >= args.length) {
10969                    name = null;
10970                    newArgs = EMPTY_STRING_ARRAY;
10971                } else {
10972                    name = args[opti];
10973                    opti++;
10974                    newArgs = new String[args.length - opti];
10975                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10976                }
10977                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10978                    pw.println("No providers match: " + name);
10979                    pw.println("Use -h for help.");
10980                }
10981            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10982                synchronized (this) {
10983                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10984                }
10985            } else if ("service".equals(cmd)) {
10986                String[] newArgs;
10987                String name;
10988                if (opti >= args.length) {
10989                    name = null;
10990                    newArgs = EMPTY_STRING_ARRAY;
10991                } else {
10992                    name = args[opti];
10993                    opti++;
10994                    newArgs = new String[args.length - opti];
10995                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10996                            args.length - opti);
10997                }
10998                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10999                    pw.println("No services match: " + name);
11000                    pw.println("Use -h for help.");
11001                }
11002            } else if ("package".equals(cmd)) {
11003                String[] newArgs;
11004                if (opti >= args.length) {
11005                    pw.println("package: no package name specified");
11006                    pw.println("Use -h for help.");
11007                } else {
11008                    dumpPackage = args[opti];
11009                    opti++;
11010                    newArgs = new String[args.length - opti];
11011                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11012                            args.length - opti);
11013                    args = newArgs;
11014                    opti = 0;
11015                    more = true;
11016                }
11017            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11018                synchronized (this) {
11019                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11020                }
11021            } else {
11022                // Dumping a single activity?
11023                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11024                    pw.println("Bad activity command, or no activities match: " + cmd);
11025                    pw.println("Use -h for help.");
11026                }
11027            }
11028            if (!more) {
11029                Binder.restoreCallingIdentity(origId);
11030                return;
11031            }
11032        }
11033
11034        // No piece of data specified, dump everything.
11035        synchronized (this) {
11036            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11037            pw.println();
11038            if (dumpAll) {
11039                pw.println("-------------------------------------------------------------------------------");
11040            }
11041            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11042            pw.println();
11043            if (dumpAll) {
11044                pw.println("-------------------------------------------------------------------------------");
11045            }
11046            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11047            pw.println();
11048            if (dumpAll) {
11049                pw.println("-------------------------------------------------------------------------------");
11050            }
11051            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11052            pw.println();
11053            if (dumpAll) {
11054                pw.println("-------------------------------------------------------------------------------");
11055            }
11056            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11057            pw.println();
11058            if (dumpAll) {
11059                pw.println("-------------------------------------------------------------------------------");
11060            }
11061            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11062        }
11063        Binder.restoreCallingIdentity(origId);
11064    }
11065
11066    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11067            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11068        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11069
11070        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11071                dumpPackage);
11072        boolean needSep = printedAnything;
11073
11074        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11075                dumpPackage, needSep, "  mFocusedActivity: ");
11076        if (printed) {
11077            printedAnything = true;
11078            needSep = false;
11079        }
11080
11081        if (dumpPackage == null) {
11082            if (needSep) {
11083                pw.println();
11084            }
11085            needSep = true;
11086            printedAnything = true;
11087            mStackSupervisor.dump(pw, "  ");
11088        }
11089
11090        if (mRecentTasks.size() > 0) {
11091            boolean printedHeader = false;
11092
11093            final int N = mRecentTasks.size();
11094            for (int i=0; i<N; i++) {
11095                TaskRecord tr = mRecentTasks.get(i);
11096                if (dumpPackage != null) {
11097                    if (tr.realActivity == null ||
11098                            !dumpPackage.equals(tr.realActivity)) {
11099                        continue;
11100                    }
11101                }
11102                if (!printedHeader) {
11103                    if (needSep) {
11104                        pw.println();
11105                    }
11106                    pw.println("  Recent tasks:");
11107                    printedHeader = true;
11108                    printedAnything = true;
11109                }
11110                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11111                        pw.println(tr);
11112                if (dumpAll) {
11113                    mRecentTasks.get(i).dump(pw, "    ");
11114                }
11115            }
11116        }
11117
11118        if (!printedAnything) {
11119            pw.println("  (nothing)");
11120        }
11121    }
11122
11123    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11124            int opti, boolean dumpAll, String dumpPackage) {
11125        boolean needSep = false;
11126        boolean printedAnything = false;
11127        int numPers = 0;
11128
11129        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11130
11131        if (dumpAll) {
11132            final int NP = mProcessNames.getMap().size();
11133            for (int ip=0; ip<NP; ip++) {
11134                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11135                final int NA = procs.size();
11136                for (int ia=0; ia<NA; ia++) {
11137                    ProcessRecord r = procs.valueAt(ia);
11138                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11139                        continue;
11140                    }
11141                    if (!needSep) {
11142                        pw.println("  All known processes:");
11143                        needSep = true;
11144                        printedAnything = true;
11145                    }
11146                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11147                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11148                        pw.print(" "); pw.println(r);
11149                    r.dump(pw, "    ");
11150                    if (r.persistent) {
11151                        numPers++;
11152                    }
11153                }
11154            }
11155        }
11156
11157        if (mIsolatedProcesses.size() > 0) {
11158            boolean printed = false;
11159            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11160                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11161                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11162                    continue;
11163                }
11164                if (!printed) {
11165                    if (needSep) {
11166                        pw.println();
11167                    }
11168                    pw.println("  Isolated process list (sorted by uid):");
11169                    printedAnything = true;
11170                    printed = true;
11171                    needSep = true;
11172                }
11173                pw.println(String.format("%sIsolated #%2d: %s",
11174                        "    ", i, r.toString()));
11175            }
11176        }
11177
11178        if (mLruProcesses.size() > 0) {
11179            if (needSep) {
11180                pw.println();
11181            }
11182            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11183                    pw.print(" total, non-act at ");
11184                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11185                    pw.print(", non-svc at ");
11186                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11187                    pw.println("):");
11188            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11189            needSep = true;
11190            printedAnything = true;
11191        }
11192
11193        if (dumpAll || dumpPackage != null) {
11194            synchronized (mPidsSelfLocked) {
11195                boolean printed = false;
11196                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11197                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11198                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11199                        continue;
11200                    }
11201                    if (!printed) {
11202                        if (needSep) pw.println();
11203                        needSep = true;
11204                        pw.println("  PID mappings:");
11205                        printed = true;
11206                        printedAnything = true;
11207                    }
11208                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11209                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11210                }
11211            }
11212        }
11213
11214        if (mForegroundProcesses.size() > 0) {
11215            synchronized (mPidsSelfLocked) {
11216                boolean printed = false;
11217                for (int i=0; i<mForegroundProcesses.size(); i++) {
11218                    ProcessRecord r = mPidsSelfLocked.get(
11219                            mForegroundProcesses.valueAt(i).pid);
11220                    if (dumpPackage != null && (r == null
11221                            || !r.pkgList.containsKey(dumpPackage))) {
11222                        continue;
11223                    }
11224                    if (!printed) {
11225                        if (needSep) pw.println();
11226                        needSep = true;
11227                        pw.println("  Foreground Processes:");
11228                        printed = true;
11229                        printedAnything = true;
11230                    }
11231                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11232                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11233                }
11234            }
11235        }
11236
11237        if (mPersistentStartingProcesses.size() > 0) {
11238            if (needSep) pw.println();
11239            needSep = true;
11240            printedAnything = true;
11241            pw.println("  Persisent processes that are starting:");
11242            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11243                    "Starting Norm", "Restarting PERS", dumpPackage);
11244        }
11245
11246        if (mRemovedProcesses.size() > 0) {
11247            if (needSep) pw.println();
11248            needSep = true;
11249            printedAnything = true;
11250            pw.println("  Processes that are being removed:");
11251            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11252                    "Removed Norm", "Removed PERS", dumpPackage);
11253        }
11254
11255        if (mProcessesOnHold.size() > 0) {
11256            if (needSep) pw.println();
11257            needSep = true;
11258            printedAnything = true;
11259            pw.println("  Processes that are on old until the system is ready:");
11260            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11261                    "OnHold Norm", "OnHold PERS", dumpPackage);
11262        }
11263
11264        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11265
11266        if (mProcessCrashTimes.getMap().size() > 0) {
11267            boolean printed = false;
11268            long now = SystemClock.uptimeMillis();
11269            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11270            final int NP = pmap.size();
11271            for (int ip=0; ip<NP; ip++) {
11272                String pname = pmap.keyAt(ip);
11273                SparseArray<Long> uids = pmap.valueAt(ip);
11274                final int N = uids.size();
11275                for (int i=0; i<N; i++) {
11276                    int puid = uids.keyAt(i);
11277                    ProcessRecord r = mProcessNames.get(pname, puid);
11278                    if (dumpPackage != null && (r == null
11279                            || !r.pkgList.containsKey(dumpPackage))) {
11280                        continue;
11281                    }
11282                    if (!printed) {
11283                        if (needSep) pw.println();
11284                        needSep = true;
11285                        pw.println("  Time since processes crashed:");
11286                        printed = true;
11287                        printedAnything = true;
11288                    }
11289                    pw.print("    Process "); pw.print(pname);
11290                            pw.print(" uid "); pw.print(puid);
11291                            pw.print(": last crashed ");
11292                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11293                            pw.println(" ago");
11294                }
11295            }
11296        }
11297
11298        if (mBadProcesses.getMap().size() > 0) {
11299            boolean printed = false;
11300            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11301            final int NP = pmap.size();
11302            for (int ip=0; ip<NP; ip++) {
11303                String pname = pmap.keyAt(ip);
11304                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11305                final int N = uids.size();
11306                for (int i=0; i<N; i++) {
11307                    int puid = uids.keyAt(i);
11308                    ProcessRecord r = mProcessNames.get(pname, puid);
11309                    if (dumpPackage != null && (r == null
11310                            || !r.pkgList.containsKey(dumpPackage))) {
11311                        continue;
11312                    }
11313                    if (!printed) {
11314                        if (needSep) pw.println();
11315                        needSep = true;
11316                        pw.println("  Bad processes:");
11317                        printedAnything = true;
11318                    }
11319                    BadProcessInfo info = uids.valueAt(i);
11320                    pw.print("    Bad process "); pw.print(pname);
11321                            pw.print(" uid "); pw.print(puid);
11322                            pw.print(": crashed at time "); pw.println(info.time);
11323                    if (info.shortMsg != null) {
11324                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11325                    }
11326                    if (info.longMsg != null) {
11327                        pw.print("      Long msg: "); pw.println(info.longMsg);
11328                    }
11329                    if (info.stack != null) {
11330                        pw.println("      Stack:");
11331                        int lastPos = 0;
11332                        for (int pos=0; pos<info.stack.length(); pos++) {
11333                            if (info.stack.charAt(pos) == '\n') {
11334                                pw.print("        ");
11335                                pw.write(info.stack, lastPos, pos-lastPos);
11336                                pw.println();
11337                                lastPos = pos+1;
11338                            }
11339                        }
11340                        if (lastPos < info.stack.length()) {
11341                            pw.print("        ");
11342                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11343                            pw.println();
11344                        }
11345                    }
11346                }
11347            }
11348        }
11349
11350        if (dumpPackage == null) {
11351            pw.println();
11352            needSep = false;
11353            pw.println("  mStartedUsers:");
11354            for (int i=0; i<mStartedUsers.size(); i++) {
11355                UserStartedState uss = mStartedUsers.valueAt(i);
11356                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11357                        pw.print(": "); uss.dump("", pw);
11358            }
11359            pw.print("  mStartedUserArray: [");
11360            for (int i=0; i<mStartedUserArray.length; i++) {
11361                if (i > 0) pw.print(", ");
11362                pw.print(mStartedUserArray[i]);
11363            }
11364            pw.println("]");
11365            pw.print("  mUserLru: [");
11366            for (int i=0; i<mUserLru.size(); i++) {
11367                if (i > 0) pw.print(", ");
11368                pw.print(mUserLru.get(i));
11369            }
11370            pw.println("]");
11371            if (dumpAll) {
11372                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11373            }
11374        }
11375        if (mHomeProcess != null && (dumpPackage == null
11376                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11377            if (needSep) {
11378                pw.println();
11379                needSep = false;
11380            }
11381            pw.println("  mHomeProcess: " + mHomeProcess);
11382        }
11383        if (mPreviousProcess != null && (dumpPackage == null
11384                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11385            if (needSep) {
11386                pw.println();
11387                needSep = false;
11388            }
11389            pw.println("  mPreviousProcess: " + mPreviousProcess);
11390        }
11391        if (dumpAll) {
11392            StringBuilder sb = new StringBuilder(128);
11393            sb.append("  mPreviousProcessVisibleTime: ");
11394            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11395            pw.println(sb);
11396        }
11397        if (mHeavyWeightProcess != null && (dumpPackage == null
11398                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11399            if (needSep) {
11400                pw.println();
11401                needSep = false;
11402            }
11403            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11404        }
11405        if (dumpPackage == null) {
11406            pw.println("  mConfiguration: " + mConfiguration);
11407        }
11408        if (dumpAll) {
11409            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11410            if (mCompatModePackages.getPackages().size() > 0) {
11411                boolean printed = false;
11412                for (Map.Entry<String, Integer> entry
11413                        : mCompatModePackages.getPackages().entrySet()) {
11414                    String pkg = entry.getKey();
11415                    int mode = entry.getValue();
11416                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11417                        continue;
11418                    }
11419                    if (!printed) {
11420                        pw.println("  mScreenCompatPackages:");
11421                        printed = true;
11422                    }
11423                    pw.print("    "); pw.print(pkg); pw.print(": ");
11424                            pw.print(mode); pw.println();
11425                }
11426            }
11427        }
11428        if (dumpPackage == null) {
11429            if (mSleeping || mWentToSleep || mLockScreenShown) {
11430                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11431                        + " mLockScreenShown " + mLockScreenShown);
11432            }
11433            if (mShuttingDown || mRunningVoice) {
11434                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11435            }
11436        }
11437        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11438                || mOrigWaitForDebugger) {
11439            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11440                    || dumpPackage.equals(mOrigDebugApp)) {
11441                if (needSep) {
11442                    pw.println();
11443                    needSep = false;
11444                }
11445                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11446                        + " mDebugTransient=" + mDebugTransient
11447                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11448            }
11449        }
11450        if (mOpenGlTraceApp != null) {
11451            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11452                if (needSep) {
11453                    pw.println();
11454                    needSep = false;
11455                }
11456                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11457            }
11458        }
11459        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11460                || mProfileFd != null) {
11461            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11462                if (needSep) {
11463                    pw.println();
11464                    needSep = false;
11465                }
11466                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11467                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11468                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11469                        + mAutoStopProfiler);
11470            }
11471        }
11472        if (dumpPackage == null) {
11473            if (mAlwaysFinishActivities || mController != null) {
11474                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11475                        + " mController=" + mController);
11476            }
11477            if (dumpAll) {
11478                pw.println("  Total persistent processes: " + numPers);
11479                pw.println("  mProcessesReady=" + mProcessesReady
11480                        + " mSystemReady=" + mSystemReady);
11481                pw.println("  mBooting=" + mBooting
11482                        + " mBooted=" + mBooted
11483                        + " mFactoryTest=" + mFactoryTest);
11484                pw.print("  mLastPowerCheckRealtime=");
11485                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11486                        pw.println("");
11487                pw.print("  mLastPowerCheckUptime=");
11488                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11489                        pw.println("");
11490                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11491                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11492                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11493                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11494                        + " (" + mLruProcesses.size() + " total)"
11495                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11496                        + " mNumServiceProcs=" + mNumServiceProcs
11497                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11498                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11499                        + " mLastMemoryLevel" + mLastMemoryLevel
11500                        + " mLastNumProcesses" + mLastNumProcesses);
11501                long now = SystemClock.uptimeMillis();
11502                pw.print("  mLastIdleTime=");
11503                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11504                        pw.print(" mLowRamSinceLastIdle=");
11505                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11506                        pw.println();
11507            }
11508        }
11509
11510        if (!printedAnything) {
11511            pw.println("  (nothing)");
11512        }
11513    }
11514
11515    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11516            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11517        if (mProcessesToGc.size() > 0) {
11518            boolean printed = false;
11519            long now = SystemClock.uptimeMillis();
11520            for (int i=0; i<mProcessesToGc.size(); i++) {
11521                ProcessRecord proc = mProcessesToGc.get(i);
11522                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11523                    continue;
11524                }
11525                if (!printed) {
11526                    if (needSep) pw.println();
11527                    needSep = true;
11528                    pw.println("  Processes that are waiting to GC:");
11529                    printed = true;
11530                }
11531                pw.print("    Process "); pw.println(proc);
11532                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11533                        pw.print(", last gced=");
11534                        pw.print(now-proc.lastRequestedGc);
11535                        pw.print(" ms ago, last lowMem=");
11536                        pw.print(now-proc.lastLowMemory);
11537                        pw.println(" ms ago");
11538
11539            }
11540        }
11541        return needSep;
11542    }
11543
11544    void printOomLevel(PrintWriter pw, String name, int adj) {
11545        pw.print("    ");
11546        if (adj >= 0) {
11547            pw.print(' ');
11548            if (adj < 10) pw.print(' ');
11549        } else {
11550            if (adj > -10) pw.print(' ');
11551        }
11552        pw.print(adj);
11553        pw.print(": ");
11554        pw.print(name);
11555        pw.print(" (");
11556        pw.print(mProcessList.getMemLevel(adj)/1024);
11557        pw.println(" kB)");
11558    }
11559
11560    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11561            int opti, boolean dumpAll) {
11562        boolean needSep = false;
11563
11564        if (mLruProcesses.size() > 0) {
11565            if (needSep) pw.println();
11566            needSep = true;
11567            pw.println("  OOM levels:");
11568            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11569            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11570            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11571            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11572            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11573            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11574            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11575            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11576            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11577            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11578            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11579            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11580            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11581
11582            if (needSep) pw.println();
11583            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11584                    pw.print(" total, non-act at ");
11585                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11586                    pw.print(", non-svc at ");
11587                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11588                    pw.println("):");
11589            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11590            needSep = true;
11591        }
11592
11593        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11594
11595        pw.println();
11596        pw.println("  mHomeProcess: " + mHomeProcess);
11597        pw.println("  mPreviousProcess: " + mPreviousProcess);
11598        if (mHeavyWeightProcess != null) {
11599            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11600        }
11601
11602        return true;
11603    }
11604
11605    /**
11606     * There are three ways to call this:
11607     *  - no provider specified: dump all the providers
11608     *  - a flattened component name that matched an existing provider was specified as the
11609     *    first arg: dump that one provider
11610     *  - the first arg isn't the flattened component name of an existing provider:
11611     *    dump all providers whose component contains the first arg as a substring
11612     */
11613    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11614            int opti, boolean dumpAll) {
11615        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11616    }
11617
11618    static class ItemMatcher {
11619        ArrayList<ComponentName> components;
11620        ArrayList<String> strings;
11621        ArrayList<Integer> objects;
11622        boolean all;
11623
11624        ItemMatcher() {
11625            all = true;
11626        }
11627
11628        void build(String name) {
11629            ComponentName componentName = ComponentName.unflattenFromString(name);
11630            if (componentName != null) {
11631                if (components == null) {
11632                    components = new ArrayList<ComponentName>();
11633                }
11634                components.add(componentName);
11635                all = false;
11636            } else {
11637                int objectId = 0;
11638                // Not a '/' separated full component name; maybe an object ID?
11639                try {
11640                    objectId = Integer.parseInt(name, 16);
11641                    if (objects == null) {
11642                        objects = new ArrayList<Integer>();
11643                    }
11644                    objects.add(objectId);
11645                    all = false;
11646                } catch (RuntimeException e) {
11647                    // Not an integer; just do string match.
11648                    if (strings == null) {
11649                        strings = new ArrayList<String>();
11650                    }
11651                    strings.add(name);
11652                    all = false;
11653                }
11654            }
11655        }
11656
11657        int build(String[] args, int opti) {
11658            for (; opti<args.length; opti++) {
11659                String name = args[opti];
11660                if ("--".equals(name)) {
11661                    return opti+1;
11662                }
11663                build(name);
11664            }
11665            return opti;
11666        }
11667
11668        boolean match(Object object, ComponentName comp) {
11669            if (all) {
11670                return true;
11671            }
11672            if (components != null) {
11673                for (int i=0; i<components.size(); i++) {
11674                    if (components.get(i).equals(comp)) {
11675                        return true;
11676                    }
11677                }
11678            }
11679            if (objects != null) {
11680                for (int i=0; i<objects.size(); i++) {
11681                    if (System.identityHashCode(object) == objects.get(i)) {
11682                        return true;
11683                    }
11684                }
11685            }
11686            if (strings != null) {
11687                String flat = comp.flattenToString();
11688                for (int i=0; i<strings.size(); i++) {
11689                    if (flat.contains(strings.get(i))) {
11690                        return true;
11691                    }
11692                }
11693            }
11694            return false;
11695        }
11696    }
11697
11698    /**
11699     * There are three things that cmd can be:
11700     *  - a flattened component name that matches an existing activity
11701     *  - the cmd arg isn't the flattened component name of an existing activity:
11702     *    dump all activity whose component contains the cmd as a substring
11703     *  - A hex number of the ActivityRecord object instance.
11704     */
11705    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11706            int opti, boolean dumpAll) {
11707        ArrayList<ActivityRecord> activities;
11708
11709        synchronized (this) {
11710            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11711        }
11712
11713        if (activities.size() <= 0) {
11714            return false;
11715        }
11716
11717        String[] newArgs = new String[args.length - opti];
11718        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11719
11720        TaskRecord lastTask = null;
11721        boolean needSep = false;
11722        for (int i=activities.size()-1; i>=0; i--) {
11723            ActivityRecord r = activities.get(i);
11724            if (needSep) {
11725                pw.println();
11726            }
11727            needSep = true;
11728            synchronized (this) {
11729                if (lastTask != r.task) {
11730                    lastTask = r.task;
11731                    pw.print("TASK "); pw.print(lastTask.affinity);
11732                            pw.print(" id="); pw.println(lastTask.taskId);
11733                    if (dumpAll) {
11734                        lastTask.dump(pw, "  ");
11735                    }
11736                }
11737            }
11738            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11739        }
11740        return true;
11741    }
11742
11743    /**
11744     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11745     * there is a thread associated with the activity.
11746     */
11747    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11748            final ActivityRecord r, String[] args, boolean dumpAll) {
11749        String innerPrefix = prefix + "  ";
11750        synchronized (this) {
11751            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11752                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11753                    pw.print(" pid=");
11754                    if (r.app != null) pw.println(r.app.pid);
11755                    else pw.println("(not running)");
11756            if (dumpAll) {
11757                r.dump(pw, innerPrefix);
11758            }
11759        }
11760        if (r.app != null && r.app.thread != null) {
11761            // flush anything that is already in the PrintWriter since the thread is going
11762            // to write to the file descriptor directly
11763            pw.flush();
11764            try {
11765                TransferPipe tp = new TransferPipe();
11766                try {
11767                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11768                            r.appToken, innerPrefix, args);
11769                    tp.go(fd);
11770                } finally {
11771                    tp.kill();
11772                }
11773            } catch (IOException e) {
11774                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11775            } catch (RemoteException e) {
11776                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11777            }
11778        }
11779    }
11780
11781    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11782            int opti, boolean dumpAll, String dumpPackage) {
11783        boolean needSep = false;
11784        boolean onlyHistory = false;
11785        boolean printedAnything = false;
11786
11787        if ("history".equals(dumpPackage)) {
11788            if (opti < args.length && "-s".equals(args[opti])) {
11789                dumpAll = false;
11790            }
11791            onlyHistory = true;
11792            dumpPackage = null;
11793        }
11794
11795        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11796        if (!onlyHistory && dumpAll) {
11797            if (mRegisteredReceivers.size() > 0) {
11798                boolean printed = false;
11799                Iterator it = mRegisteredReceivers.values().iterator();
11800                while (it.hasNext()) {
11801                    ReceiverList r = (ReceiverList)it.next();
11802                    if (dumpPackage != null && (r.app == null ||
11803                            !dumpPackage.equals(r.app.info.packageName))) {
11804                        continue;
11805                    }
11806                    if (!printed) {
11807                        pw.println("  Registered Receivers:");
11808                        needSep = true;
11809                        printed = true;
11810                        printedAnything = true;
11811                    }
11812                    pw.print("  * "); pw.println(r);
11813                    r.dump(pw, "    ");
11814                }
11815            }
11816
11817            if (mReceiverResolver.dump(pw, needSep ?
11818                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11819                    "    ", dumpPackage, false)) {
11820                needSep = true;
11821                printedAnything = true;
11822            }
11823        }
11824
11825        for (BroadcastQueue q : mBroadcastQueues) {
11826            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11827            printedAnything |= needSep;
11828        }
11829
11830        needSep = true;
11831
11832        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11833            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11834                if (needSep) {
11835                    pw.println();
11836                }
11837                needSep = true;
11838                printedAnything = true;
11839                pw.print("  Sticky broadcasts for user ");
11840                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11841                StringBuilder sb = new StringBuilder(128);
11842                for (Map.Entry<String, ArrayList<Intent>> ent
11843                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11844                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11845                    if (dumpAll) {
11846                        pw.println(":");
11847                        ArrayList<Intent> intents = ent.getValue();
11848                        final int N = intents.size();
11849                        for (int i=0; i<N; i++) {
11850                            sb.setLength(0);
11851                            sb.append("    Intent: ");
11852                            intents.get(i).toShortString(sb, false, true, false, false);
11853                            pw.println(sb.toString());
11854                            Bundle bundle = intents.get(i).getExtras();
11855                            if (bundle != null) {
11856                                pw.print("      ");
11857                                pw.println(bundle.toString());
11858                            }
11859                        }
11860                    } else {
11861                        pw.println("");
11862                    }
11863                }
11864            }
11865        }
11866
11867        if (!onlyHistory && dumpAll) {
11868            pw.println();
11869            for (BroadcastQueue queue : mBroadcastQueues) {
11870                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11871                        + queue.mBroadcastsScheduled);
11872            }
11873            pw.println("  mHandler:");
11874            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11875            needSep = true;
11876            printedAnything = true;
11877        }
11878
11879        if (!printedAnything) {
11880            pw.println("  (nothing)");
11881        }
11882    }
11883
11884    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11885            int opti, boolean dumpAll, String dumpPackage) {
11886        boolean needSep;
11887        boolean printedAnything = false;
11888
11889        ItemMatcher matcher = new ItemMatcher();
11890        matcher.build(args, opti);
11891
11892        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11893
11894        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11895        printedAnything |= needSep;
11896
11897        if (mLaunchingProviders.size() > 0) {
11898            boolean printed = false;
11899            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11900                ContentProviderRecord r = mLaunchingProviders.get(i);
11901                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11902                    continue;
11903                }
11904                if (!printed) {
11905                    if (needSep) pw.println();
11906                    needSep = true;
11907                    pw.println("  Launching content providers:");
11908                    printed = true;
11909                    printedAnything = true;
11910                }
11911                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11912                        pw.println(r);
11913            }
11914        }
11915
11916        if (mGrantedUriPermissions.size() > 0) {
11917            boolean printed = false;
11918            int dumpUid = -2;
11919            if (dumpPackage != null) {
11920                try {
11921                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11922                } catch (NameNotFoundException e) {
11923                    dumpUid = -1;
11924                }
11925            }
11926            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11927                int uid = mGrantedUriPermissions.keyAt(i);
11928                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11929                    continue;
11930                }
11931                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11932                if (!printed) {
11933                    if (needSep) pw.println();
11934                    needSep = true;
11935                    pw.println("  Granted Uri Permissions:");
11936                    printed = true;
11937                    printedAnything = true;
11938                }
11939                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11940                for (UriPermission perm : perms.values()) {
11941                    pw.print("    "); pw.println(perm);
11942                    if (dumpAll) {
11943                        perm.dump(pw, "      ");
11944                    }
11945                }
11946            }
11947        }
11948
11949        if (!printedAnything) {
11950            pw.println("  (nothing)");
11951        }
11952    }
11953
11954    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11955            int opti, boolean dumpAll, String dumpPackage) {
11956        boolean printed = false;
11957
11958        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11959
11960        if (mIntentSenderRecords.size() > 0) {
11961            Iterator<WeakReference<PendingIntentRecord>> it
11962                    = mIntentSenderRecords.values().iterator();
11963            while (it.hasNext()) {
11964                WeakReference<PendingIntentRecord> ref = it.next();
11965                PendingIntentRecord rec = ref != null ? ref.get(): null;
11966                if (dumpPackage != null && (rec == null
11967                        || !dumpPackage.equals(rec.key.packageName))) {
11968                    continue;
11969                }
11970                printed = true;
11971                if (rec != null) {
11972                    pw.print("  * "); pw.println(rec);
11973                    if (dumpAll) {
11974                        rec.dump(pw, "    ");
11975                    }
11976                } else {
11977                    pw.print("  * "); pw.println(ref);
11978                }
11979            }
11980        }
11981
11982        if (!printed) {
11983            pw.println("  (nothing)");
11984        }
11985    }
11986
11987    private static final int dumpProcessList(PrintWriter pw,
11988            ActivityManagerService service, List list,
11989            String prefix, String normalLabel, String persistentLabel,
11990            String dumpPackage) {
11991        int numPers = 0;
11992        final int N = list.size()-1;
11993        for (int i=N; i>=0; i--) {
11994            ProcessRecord r = (ProcessRecord)list.get(i);
11995            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11996                continue;
11997            }
11998            pw.println(String.format("%s%s #%2d: %s",
11999                    prefix, (r.persistent ? persistentLabel : normalLabel),
12000                    i, r.toString()));
12001            if (r.persistent) {
12002                numPers++;
12003            }
12004        }
12005        return numPers;
12006    }
12007
12008    private static final boolean dumpProcessOomList(PrintWriter pw,
12009            ActivityManagerService service, List<ProcessRecord> origList,
12010            String prefix, String normalLabel, String persistentLabel,
12011            boolean inclDetails, String dumpPackage) {
12012
12013        ArrayList<Pair<ProcessRecord, Integer>> list
12014                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12015        for (int i=0; i<origList.size(); i++) {
12016            ProcessRecord r = origList.get(i);
12017            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12018                continue;
12019            }
12020            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12021        }
12022
12023        if (list.size() <= 0) {
12024            return false;
12025        }
12026
12027        Comparator<Pair<ProcessRecord, Integer>> comparator
12028                = new Comparator<Pair<ProcessRecord, Integer>>() {
12029            @Override
12030            public int compare(Pair<ProcessRecord, Integer> object1,
12031                    Pair<ProcessRecord, Integer> object2) {
12032                if (object1.first.setAdj != object2.first.setAdj) {
12033                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12034                }
12035                if (object1.second.intValue() != object2.second.intValue()) {
12036                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12037                }
12038                return 0;
12039            }
12040        };
12041
12042        Collections.sort(list, comparator);
12043
12044        final long curRealtime = SystemClock.elapsedRealtime();
12045        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12046        final long curUptime = SystemClock.uptimeMillis();
12047        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12048
12049        for (int i=list.size()-1; i>=0; i--) {
12050            ProcessRecord r = list.get(i).first;
12051            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12052            char schedGroup;
12053            switch (r.setSchedGroup) {
12054                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12055                    schedGroup = 'B';
12056                    break;
12057                case Process.THREAD_GROUP_DEFAULT:
12058                    schedGroup = 'F';
12059                    break;
12060                default:
12061                    schedGroup = '?';
12062                    break;
12063            }
12064            char foreground;
12065            if (r.foregroundActivities) {
12066                foreground = 'A';
12067            } else if (r.foregroundServices) {
12068                foreground = 'S';
12069            } else {
12070                foreground = ' ';
12071            }
12072            String procState = ProcessList.makeProcStateString(r.curProcState);
12073            pw.print(prefix);
12074            pw.print(r.persistent ? persistentLabel : normalLabel);
12075            pw.print(" #");
12076            int num = (origList.size()-1)-list.get(i).second;
12077            if (num < 10) pw.print(' ');
12078            pw.print(num);
12079            pw.print(": ");
12080            pw.print(oomAdj);
12081            pw.print(' ');
12082            pw.print(schedGroup);
12083            pw.print('/');
12084            pw.print(foreground);
12085            pw.print('/');
12086            pw.print(procState);
12087            pw.print(" trm:");
12088            if (r.trimMemoryLevel < 10) pw.print(' ');
12089            pw.print(r.trimMemoryLevel);
12090            pw.print(' ');
12091            pw.print(r.toShortString());
12092            pw.print(" (");
12093            pw.print(r.adjType);
12094            pw.println(')');
12095            if (r.adjSource != null || r.adjTarget != null) {
12096                pw.print(prefix);
12097                pw.print("    ");
12098                if (r.adjTarget instanceof ComponentName) {
12099                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12100                } else if (r.adjTarget != null) {
12101                    pw.print(r.adjTarget.toString());
12102                } else {
12103                    pw.print("{null}");
12104                }
12105                pw.print("<=");
12106                if (r.adjSource instanceof ProcessRecord) {
12107                    pw.print("Proc{");
12108                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12109                    pw.println("}");
12110                } else if (r.adjSource != null) {
12111                    pw.println(r.adjSource.toString());
12112                } else {
12113                    pw.println("{null}");
12114                }
12115            }
12116            if (inclDetails) {
12117                pw.print(prefix);
12118                pw.print("    ");
12119                pw.print("oom: max="); pw.print(r.maxAdj);
12120                pw.print(" curRaw="); pw.print(r.curRawAdj);
12121                pw.print(" setRaw="); pw.print(r.setRawAdj);
12122                pw.print(" cur="); pw.print(r.curAdj);
12123                pw.print(" set="); pw.println(r.setAdj);
12124                pw.print(prefix);
12125                pw.print("    ");
12126                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12127                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12128                pw.print(" lastPss="); pw.print(r.lastPss);
12129                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12130                pw.print(prefix);
12131                pw.print("    ");
12132                pw.print("keeping="); pw.print(r.keeping);
12133                pw.print(" cached="); pw.print(r.cached);
12134                pw.print(" empty="); pw.print(r.empty);
12135                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12136
12137                if (!r.keeping) {
12138                    if (r.lastWakeTime != 0) {
12139                        long wtime;
12140                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12141                        synchronized (stats) {
12142                            wtime = stats.getProcessWakeTime(r.info.uid,
12143                                    r.pid, curRealtime);
12144                        }
12145                        long timeUsed = wtime - r.lastWakeTime;
12146                        pw.print(prefix);
12147                        pw.print("    ");
12148                        pw.print("keep awake over ");
12149                        TimeUtils.formatDuration(realtimeSince, pw);
12150                        pw.print(" used ");
12151                        TimeUtils.formatDuration(timeUsed, pw);
12152                        pw.print(" (");
12153                        pw.print((timeUsed*100)/realtimeSince);
12154                        pw.println("%)");
12155                    }
12156                    if (r.lastCpuTime != 0) {
12157                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12158                        pw.print(prefix);
12159                        pw.print("    ");
12160                        pw.print("run cpu over ");
12161                        TimeUtils.formatDuration(uptimeSince, pw);
12162                        pw.print(" used ");
12163                        TimeUtils.formatDuration(timeUsed, pw);
12164                        pw.print(" (");
12165                        pw.print((timeUsed*100)/uptimeSince);
12166                        pw.println("%)");
12167                    }
12168                }
12169            }
12170        }
12171        return true;
12172    }
12173
12174    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12175        ArrayList<ProcessRecord> procs;
12176        synchronized (this) {
12177            if (args != null && args.length > start
12178                    && args[start].charAt(0) != '-') {
12179                procs = new ArrayList<ProcessRecord>();
12180                int pid = -1;
12181                try {
12182                    pid = Integer.parseInt(args[start]);
12183                } catch (NumberFormatException e) {
12184                }
12185                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12186                    ProcessRecord proc = mLruProcesses.get(i);
12187                    if (proc.pid == pid) {
12188                        procs.add(proc);
12189                    } else if (proc.processName.equals(args[start])) {
12190                        procs.add(proc);
12191                    }
12192                }
12193                if (procs.size() <= 0) {
12194                    return null;
12195                }
12196            } else {
12197                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12198            }
12199        }
12200        return procs;
12201    }
12202
12203    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12204            PrintWriter pw, String[] args) {
12205        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12206        if (procs == null) {
12207            pw.println("No process found for: " + args[0]);
12208            return;
12209        }
12210
12211        long uptime = SystemClock.uptimeMillis();
12212        long realtime = SystemClock.elapsedRealtime();
12213        pw.println("Applications Graphics Acceleration Info:");
12214        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12215
12216        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12217            ProcessRecord r = procs.get(i);
12218            if (r.thread != null) {
12219                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12220                pw.flush();
12221                try {
12222                    TransferPipe tp = new TransferPipe();
12223                    try {
12224                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12225                        tp.go(fd);
12226                    } finally {
12227                        tp.kill();
12228                    }
12229                } catch (IOException e) {
12230                    pw.println("Failure while dumping the app: " + r);
12231                    pw.flush();
12232                } catch (RemoteException e) {
12233                    pw.println("Got a RemoteException while dumping the app " + r);
12234                    pw.flush();
12235                }
12236            }
12237        }
12238    }
12239
12240    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12241        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12242        if (procs == null) {
12243            pw.println("No process found for: " + args[0]);
12244            return;
12245        }
12246
12247        pw.println("Applications Database Info:");
12248
12249        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12250            ProcessRecord r = procs.get(i);
12251            if (r.thread != null) {
12252                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12253                pw.flush();
12254                try {
12255                    TransferPipe tp = new TransferPipe();
12256                    try {
12257                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12258                        tp.go(fd);
12259                    } finally {
12260                        tp.kill();
12261                    }
12262                } catch (IOException e) {
12263                    pw.println("Failure while dumping the app: " + r);
12264                    pw.flush();
12265                } catch (RemoteException e) {
12266                    pw.println("Got a RemoteException while dumping the app " + r);
12267                    pw.flush();
12268                }
12269            }
12270        }
12271    }
12272
12273    final static class MemItem {
12274        final boolean isProc;
12275        final String label;
12276        final String shortLabel;
12277        final long pss;
12278        final int id;
12279        final boolean hasActivities;
12280        ArrayList<MemItem> subitems;
12281
12282        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12283                boolean _hasActivities) {
12284            isProc = true;
12285            label = _label;
12286            shortLabel = _shortLabel;
12287            pss = _pss;
12288            id = _id;
12289            hasActivities = _hasActivities;
12290        }
12291
12292        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12293            isProc = false;
12294            label = _label;
12295            shortLabel = _shortLabel;
12296            pss = _pss;
12297            id = _id;
12298            hasActivities = false;
12299        }
12300    }
12301
12302    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12303            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12304        if (sort && !isCompact) {
12305            Collections.sort(items, new Comparator<MemItem>() {
12306                @Override
12307                public int compare(MemItem lhs, MemItem rhs) {
12308                    if (lhs.pss < rhs.pss) {
12309                        return 1;
12310                    } else if (lhs.pss > rhs.pss) {
12311                        return -1;
12312                    }
12313                    return 0;
12314                }
12315            });
12316        }
12317
12318        for (int i=0; i<items.size(); i++) {
12319            MemItem mi = items.get(i);
12320            if (!isCompact) {
12321                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12322            } else if (mi.isProc) {
12323                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12324                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12325                pw.println(mi.hasActivities ? ",a" : ",e");
12326            } else {
12327                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12328                pw.println(mi.pss);
12329            }
12330            if (mi.subitems != null) {
12331                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12332                        true, isCompact);
12333            }
12334        }
12335    }
12336
12337    // These are in KB.
12338    static final long[] DUMP_MEM_BUCKETS = new long[] {
12339        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12340        120*1024, 160*1024, 200*1024,
12341        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12342        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12343    };
12344
12345    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12346            boolean stackLike) {
12347        int start = label.lastIndexOf('.');
12348        if (start >= 0) start++;
12349        else start = 0;
12350        int end = label.length();
12351        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12352            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12353                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12354                out.append(bucket);
12355                out.append(stackLike ? "MB." : "MB ");
12356                out.append(label, start, end);
12357                return;
12358            }
12359        }
12360        out.append(memKB/1024);
12361        out.append(stackLike ? "MB." : "MB ");
12362        out.append(label, start, end);
12363    }
12364
12365    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12366            ProcessList.NATIVE_ADJ,
12367            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12368            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12369            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12370            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12371            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12372    };
12373    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12374            "Native",
12375            "System", "Persistent", "Foreground",
12376            "Visible", "Perceptible",
12377            "Heavy Weight", "Backup",
12378            "A Services", "Home",
12379            "Previous", "B Services", "Cached"
12380    };
12381    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12382            "native",
12383            "sys", "pers", "fore",
12384            "vis", "percept",
12385            "heavy", "backup",
12386            "servicea", "home",
12387            "prev", "serviceb", "cached"
12388    };
12389
12390    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12391            long realtime, boolean isCheckinRequest, boolean isCompact) {
12392        if (isCheckinRequest || isCompact) {
12393            // short checkin version
12394            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12395        } else {
12396            pw.println("Applications Memory Usage (kB):");
12397            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12398        }
12399    }
12400
12401    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12402            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12403        boolean dumpDetails = false;
12404        boolean dumpFullDetails = false;
12405        boolean dumpDalvik = false;
12406        boolean oomOnly = false;
12407        boolean isCompact = false;
12408        boolean localOnly = false;
12409
12410        int opti = 0;
12411        while (opti < args.length) {
12412            String opt = args[opti];
12413            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12414                break;
12415            }
12416            opti++;
12417            if ("-a".equals(opt)) {
12418                dumpDetails = true;
12419                dumpFullDetails = true;
12420                dumpDalvik = true;
12421            } else if ("-d".equals(opt)) {
12422                dumpDalvik = true;
12423            } else if ("-c".equals(opt)) {
12424                isCompact = true;
12425            } else if ("--oom".equals(opt)) {
12426                oomOnly = true;
12427            } else if ("--local".equals(opt)) {
12428                localOnly = true;
12429            } else if ("-h".equals(opt)) {
12430                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12431                pw.println("  -a: include all available information for each process.");
12432                pw.println("  -d: include dalvik details when dumping process details.");
12433                pw.println("  -c: dump in a compact machine-parseable representation.");
12434                pw.println("  --oom: only show processes organized by oom adj.");
12435                pw.println("  --local: only collect details locally, don't call process.");
12436                pw.println("If [process] is specified it can be the name or ");
12437                pw.println("pid of a specific process to dump.");
12438                return;
12439            } else {
12440                pw.println("Unknown argument: " + opt + "; use -h for help");
12441            }
12442        }
12443
12444        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12445        long uptime = SystemClock.uptimeMillis();
12446        long realtime = SystemClock.elapsedRealtime();
12447        final long[] tmpLong = new long[1];
12448
12449        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12450        if (procs == null) {
12451            // No Java processes.  Maybe they want to print a native process.
12452            if (args != null && args.length > opti
12453                    && args[opti].charAt(0) != '-') {
12454                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12455                        = new ArrayList<ProcessCpuTracker.Stats>();
12456                updateCpuStatsNow();
12457                int findPid = -1;
12458                try {
12459                    findPid = Integer.parseInt(args[opti]);
12460                } catch (NumberFormatException e) {
12461                }
12462                synchronized (mProcessCpuThread) {
12463                    final int N = mProcessCpuTracker.countStats();
12464                    for (int i=0; i<N; i++) {
12465                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12466                        if (st.pid == findPid || (st.baseName != null
12467                                && st.baseName.equals(args[opti]))) {
12468                            nativeProcs.add(st);
12469                        }
12470                    }
12471                }
12472                if (nativeProcs.size() > 0) {
12473                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12474                            isCompact);
12475                    Debug.MemoryInfo mi = null;
12476                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12477                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12478                        final int pid = r.pid;
12479                        if (!isCheckinRequest && dumpDetails) {
12480                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12481                        }
12482                        if (mi == null) {
12483                            mi = new Debug.MemoryInfo();
12484                        }
12485                        if (dumpDetails || (!brief && !oomOnly)) {
12486                            Debug.getMemoryInfo(pid, mi);
12487                        } else {
12488                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12489                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12490                        }
12491                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12492                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12493                        if (isCheckinRequest) {
12494                            pw.println();
12495                        }
12496                    }
12497                    return;
12498                }
12499            }
12500            pw.println("No process found for: " + args[opti]);
12501            return;
12502        }
12503
12504        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12505            dumpDetails = true;
12506        }
12507
12508        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12509
12510        String[] innerArgs = new String[args.length-opti];
12511        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12512
12513        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12514        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12515        long nativePss=0, dalvikPss=0, otherPss=0;
12516        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12517
12518        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12519        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12520                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12521
12522        long totalPss = 0;
12523        long cachedPss = 0;
12524
12525        Debug.MemoryInfo mi = null;
12526        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12527            final ProcessRecord r = procs.get(i);
12528            final IApplicationThread thread;
12529            final int pid;
12530            final int oomAdj;
12531            final boolean hasActivities;
12532            synchronized (this) {
12533                thread = r.thread;
12534                pid = r.pid;
12535                oomAdj = r.getSetAdjWithServices();
12536                hasActivities = r.activities.size() > 0;
12537            }
12538            if (thread != null) {
12539                if (!isCheckinRequest && dumpDetails) {
12540                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12541                }
12542                if (mi == null) {
12543                    mi = new Debug.MemoryInfo();
12544                }
12545                if (dumpDetails || (!brief && !oomOnly)) {
12546                    Debug.getMemoryInfo(pid, mi);
12547                } else {
12548                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12549                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12550                }
12551                if (dumpDetails) {
12552                    if (localOnly) {
12553                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12554                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12555                        if (isCheckinRequest) {
12556                            pw.println();
12557                        }
12558                    } else {
12559                        try {
12560                            pw.flush();
12561                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12562                                    dumpDalvik, innerArgs);
12563                        } catch (RemoteException e) {
12564                            if (!isCheckinRequest) {
12565                                pw.println("Got RemoteException!");
12566                                pw.flush();
12567                            }
12568                        }
12569                    }
12570                }
12571
12572                final long myTotalPss = mi.getTotalPss();
12573                final long myTotalUss = mi.getTotalUss();
12574
12575                synchronized (this) {
12576                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12577                        // Record this for posterity if the process has been stable.
12578                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12579                    }
12580                }
12581
12582                if (!isCheckinRequest && mi != null) {
12583                    totalPss += myTotalPss;
12584                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12585                            (hasActivities ? " / activities)" : ")"),
12586                            r.processName, myTotalPss, pid, hasActivities);
12587                    procMems.add(pssItem);
12588                    procMemsMap.put(pid, pssItem);
12589
12590                    nativePss += mi.nativePss;
12591                    dalvikPss += mi.dalvikPss;
12592                    otherPss += mi.otherPss;
12593                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12594                        long mem = mi.getOtherPss(j);
12595                        miscPss[j] += mem;
12596                        otherPss -= mem;
12597                    }
12598
12599                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12600                        cachedPss += myTotalPss;
12601                    }
12602
12603                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12604                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12605                                || oomIndex == (oomPss.length-1)) {
12606                            oomPss[oomIndex] += myTotalPss;
12607                            if (oomProcs[oomIndex] == null) {
12608                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12609                            }
12610                            oomProcs[oomIndex].add(pssItem);
12611                            break;
12612                        }
12613                    }
12614                }
12615            }
12616        }
12617
12618        long nativeProcTotalPss = 0;
12619
12620        if (!isCheckinRequest && procs.size() > 1) {
12621            // If we are showing aggregations, also look for native processes to
12622            // include so that our aggregations are more accurate.
12623            updateCpuStatsNow();
12624            synchronized (mProcessCpuThread) {
12625                final int N = mProcessCpuTracker.countStats();
12626                for (int i=0; i<N; i++) {
12627                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12628                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12629                        if (mi == null) {
12630                            mi = new Debug.MemoryInfo();
12631                        }
12632                        if (!brief && !oomOnly) {
12633                            Debug.getMemoryInfo(st.pid, mi);
12634                        } else {
12635                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12636                            mi.nativePrivateDirty = (int)tmpLong[0];
12637                        }
12638
12639                        final long myTotalPss = mi.getTotalPss();
12640                        totalPss += myTotalPss;
12641                        nativeProcTotalPss += myTotalPss;
12642
12643                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12644                                st.name, myTotalPss, st.pid, false);
12645                        procMems.add(pssItem);
12646
12647                        nativePss += mi.nativePss;
12648                        dalvikPss += mi.dalvikPss;
12649                        otherPss += mi.otherPss;
12650                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12651                            long mem = mi.getOtherPss(j);
12652                            miscPss[j] += mem;
12653                            otherPss -= mem;
12654                        }
12655                        oomPss[0] += myTotalPss;
12656                        if (oomProcs[0] == null) {
12657                            oomProcs[0] = new ArrayList<MemItem>();
12658                        }
12659                        oomProcs[0].add(pssItem);
12660                    }
12661                }
12662            }
12663
12664            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12665
12666            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12667            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12668            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12669            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12670                String label = Debug.MemoryInfo.getOtherLabel(j);
12671                catMems.add(new MemItem(label, label, miscPss[j], j));
12672            }
12673
12674            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12675            for (int j=0; j<oomPss.length; j++) {
12676                if (oomPss[j] != 0) {
12677                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12678                            : DUMP_MEM_OOM_LABEL[j];
12679                    MemItem item = new MemItem(label, label, oomPss[j],
12680                            DUMP_MEM_OOM_ADJ[j]);
12681                    item.subitems = oomProcs[j];
12682                    oomMems.add(item);
12683                }
12684            }
12685
12686            if (!brief && !oomOnly && !isCompact) {
12687                pw.println();
12688                pw.println("Total PSS by process:");
12689                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12690                pw.println();
12691            }
12692            if (!isCompact) {
12693                pw.println("Total PSS by OOM adjustment:");
12694            }
12695            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12696            if (!brief && !oomOnly) {
12697                PrintWriter out = categoryPw != null ? categoryPw : pw;
12698                if (!isCompact) {
12699                    out.println();
12700                    out.println("Total PSS by category:");
12701                }
12702                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12703            }
12704            if (!isCompact) {
12705                pw.println();
12706            }
12707            MemInfoReader memInfo = new MemInfoReader();
12708            memInfo.readMemInfo();
12709            if (nativeProcTotalPss > 0) {
12710                synchronized (this) {
12711                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12712                            memInfo.getFreeSizeKb(),
12713                            memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
12714                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12715                            nativeProcTotalPss);
12716                }
12717            }
12718            if (!brief) {
12719                if (!isCompact) {
12720                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12721                    pw.print(" kB (status ");
12722                    switch (mLastMemoryLevel) {
12723                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12724                            pw.println("normal)");
12725                            break;
12726                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12727                            pw.println("moderate)");
12728                            break;
12729                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12730                            pw.println("low)");
12731                            break;
12732                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12733                            pw.println("critical)");
12734                            break;
12735                        default:
12736                            pw.print(mLastMemoryLevel);
12737                            pw.println(")");
12738                            break;
12739                    }
12740                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12741                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12742                            pw.print(cachedPss); pw.print(" cached pss + ");
12743                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12744                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12745                } else {
12746                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12747                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12748                            + memInfo.getFreeSizeKb()); pw.print(",");
12749                    pw.println(totalPss - cachedPss);
12750                }
12751            }
12752            if (!isCompact) {
12753                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12754                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12755                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12756                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12757                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12758                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12759                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12760                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12761                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12762                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12763                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12764            }
12765            if (!brief) {
12766                if (memInfo.getZramTotalSizeKb() != 0) {
12767                    if (!isCompact) {
12768                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12769                                pw.print(" kB physical used for ");
12770                                pw.print(memInfo.getSwapTotalSizeKb()
12771                                        - memInfo.getSwapFreeSizeKb());
12772                                pw.print(" kB in swap (");
12773                                pw.print(memInfo.getSwapTotalSizeKb());
12774                                pw.println(" kB total swap)");
12775                    } else {
12776                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12777                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12778                                pw.println(memInfo.getSwapFreeSizeKb());
12779                    }
12780                }
12781                final int[] SINGLE_LONG_FORMAT = new int[] {
12782                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12783                };
12784                long[] longOut = new long[1];
12785                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12786                        SINGLE_LONG_FORMAT, null, longOut, null);
12787                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12788                longOut[0] = 0;
12789                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12790                        SINGLE_LONG_FORMAT, null, longOut, null);
12791                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12792                longOut[0] = 0;
12793                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12794                        SINGLE_LONG_FORMAT, null, longOut, null);
12795                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12796                longOut[0] = 0;
12797                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12798                        SINGLE_LONG_FORMAT, null, longOut, null);
12799                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12800                if (!isCompact) {
12801                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12802                        pw.print("      KSM: "); pw.print(sharing);
12803                                pw.print(" kB saved from shared ");
12804                                pw.print(shared); pw.println(" kB");
12805                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12806                                pw.print(voltile); pw.println(" kB volatile");
12807                    }
12808                    pw.print("   Tuning: ");
12809                    pw.print(ActivityManager.staticGetMemoryClass());
12810                    pw.print(" (large ");
12811                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12812                    pw.print("), oom ");
12813                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12814                    pw.print(" kB");
12815                    pw.print(", restore limit ");
12816                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12817                    pw.print(" kB");
12818                    if (ActivityManager.isLowRamDeviceStatic()) {
12819                        pw.print(" (low-ram)");
12820                    }
12821                    if (ActivityManager.isHighEndGfx()) {
12822                        pw.print(" (high-end-gfx)");
12823                    }
12824                    pw.println();
12825                } else {
12826                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12827                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12828                    pw.println(voltile);
12829                    pw.print("tuning,");
12830                    pw.print(ActivityManager.staticGetMemoryClass());
12831                    pw.print(',');
12832                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12833                    pw.print(',');
12834                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12835                    if (ActivityManager.isLowRamDeviceStatic()) {
12836                        pw.print(",low-ram");
12837                    }
12838                    if (ActivityManager.isHighEndGfx()) {
12839                        pw.print(",high-end-gfx");
12840                    }
12841                    pw.println();
12842                }
12843            }
12844        }
12845    }
12846
12847    /**
12848     * Searches array of arguments for the specified string
12849     * @param args array of argument strings
12850     * @param value value to search for
12851     * @return true if the value is contained in the array
12852     */
12853    private static boolean scanArgs(String[] args, String value) {
12854        if (args != null) {
12855            for (String arg : args) {
12856                if (value.equals(arg)) {
12857                    return true;
12858                }
12859            }
12860        }
12861        return false;
12862    }
12863
12864    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12865            ContentProviderRecord cpr, boolean always) {
12866        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12867
12868        if (!inLaunching || always) {
12869            synchronized (cpr) {
12870                cpr.launchingApp = null;
12871                cpr.notifyAll();
12872            }
12873            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12874            String names[] = cpr.info.authority.split(";");
12875            for (int j = 0; j < names.length; j++) {
12876                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12877            }
12878        }
12879
12880        for (int i=0; i<cpr.connections.size(); i++) {
12881            ContentProviderConnection conn = cpr.connections.get(i);
12882            if (conn.waiting) {
12883                // If this connection is waiting for the provider, then we don't
12884                // need to mess with its process unless we are always removing
12885                // or for some reason the provider is not currently launching.
12886                if (inLaunching && !always) {
12887                    continue;
12888                }
12889            }
12890            ProcessRecord capp = conn.client;
12891            conn.dead = true;
12892            if (conn.stableCount > 0) {
12893                if (!capp.persistent && capp.thread != null
12894                        && capp.pid != 0
12895                        && capp.pid != MY_PID) {
12896                    killUnneededProcessLocked(capp, "depends on provider "
12897                            + cpr.name.flattenToShortString()
12898                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12899                }
12900            } else if (capp.thread != null && conn.provider.provider != null) {
12901                try {
12902                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12903                } catch (RemoteException e) {
12904                }
12905                // In the protocol here, we don't expect the client to correctly
12906                // clean up this connection, we'll just remove it.
12907                cpr.connections.remove(i);
12908                conn.client.conProviders.remove(conn);
12909            }
12910        }
12911
12912        if (inLaunching && always) {
12913            mLaunchingProviders.remove(cpr);
12914        }
12915        return inLaunching;
12916    }
12917
12918    /**
12919     * Main code for cleaning up a process when it has gone away.  This is
12920     * called both as a result of the process dying, or directly when stopping
12921     * a process when running in single process mode.
12922     */
12923    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12924            boolean restarting, boolean allowRestart, int index) {
12925        if (index >= 0) {
12926            removeLruProcessLocked(app);
12927            ProcessList.remove(app.pid);
12928        }
12929
12930        mProcessesToGc.remove(app);
12931        mPendingPssProcesses.remove(app);
12932
12933        // Dismiss any open dialogs.
12934        if (app.crashDialog != null && !app.forceCrashReport) {
12935            app.crashDialog.dismiss();
12936            app.crashDialog = null;
12937        }
12938        if (app.anrDialog != null) {
12939            app.anrDialog.dismiss();
12940            app.anrDialog = null;
12941        }
12942        if (app.waitDialog != null) {
12943            app.waitDialog.dismiss();
12944            app.waitDialog = null;
12945        }
12946
12947        app.crashing = false;
12948        app.notResponding = false;
12949
12950        app.resetPackageList(mProcessStats);
12951        app.unlinkDeathRecipient();
12952        app.makeInactive(mProcessStats);
12953        app.forcingToForeground = null;
12954        updateProcessForegroundLocked(app, false, false);
12955        app.foregroundActivities = false;
12956        app.hasShownUi = false;
12957        app.treatLikeActivity = false;
12958        app.hasAboveClient = false;
12959        app.hasClientActivities = false;
12960
12961        mServices.killServicesLocked(app, allowRestart);
12962
12963        boolean restart = false;
12964
12965        // Remove published content providers.
12966        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12967            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12968            final boolean always = app.bad || !allowRestart;
12969            if (removeDyingProviderLocked(app, cpr, always) || always) {
12970                // We left the provider in the launching list, need to
12971                // restart it.
12972                restart = true;
12973            }
12974
12975            cpr.provider = null;
12976            cpr.proc = null;
12977        }
12978        app.pubProviders.clear();
12979
12980        // Take care of any launching providers waiting for this process.
12981        if (checkAppInLaunchingProvidersLocked(app, false)) {
12982            restart = true;
12983        }
12984
12985        // Unregister from connected content providers.
12986        if (!app.conProviders.isEmpty()) {
12987            for (int i=0; i<app.conProviders.size(); i++) {
12988                ContentProviderConnection conn = app.conProviders.get(i);
12989                conn.provider.connections.remove(conn);
12990            }
12991            app.conProviders.clear();
12992        }
12993
12994        // At this point there may be remaining entries in mLaunchingProviders
12995        // where we were the only one waiting, so they are no longer of use.
12996        // Look for these and clean up if found.
12997        // XXX Commented out for now.  Trying to figure out a way to reproduce
12998        // the actual situation to identify what is actually going on.
12999        if (false) {
13000            for (int i=0; i<mLaunchingProviders.size(); i++) {
13001                ContentProviderRecord cpr = (ContentProviderRecord)
13002                        mLaunchingProviders.get(i);
13003                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13004                    synchronized (cpr) {
13005                        cpr.launchingApp = null;
13006                        cpr.notifyAll();
13007                    }
13008                }
13009            }
13010        }
13011
13012        skipCurrentReceiverLocked(app);
13013
13014        // Unregister any receivers.
13015        for (int i=app.receivers.size()-1; i>=0; i--) {
13016            removeReceiverLocked(app.receivers.valueAt(i));
13017        }
13018        app.receivers.clear();
13019
13020        // If the app is undergoing backup, tell the backup manager about it
13021        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13022            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13023                    + mBackupTarget.appInfo + " died during backup");
13024            try {
13025                IBackupManager bm = IBackupManager.Stub.asInterface(
13026                        ServiceManager.getService(Context.BACKUP_SERVICE));
13027                bm.agentDisconnected(app.info.packageName);
13028            } catch (RemoteException e) {
13029                // can't happen; backup manager is local
13030            }
13031        }
13032
13033        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13034            ProcessChangeItem item = mPendingProcessChanges.get(i);
13035            if (item.pid == app.pid) {
13036                mPendingProcessChanges.remove(i);
13037                mAvailProcessChanges.add(item);
13038            }
13039        }
13040        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13041
13042        // If the caller is restarting this app, then leave it in its
13043        // current lists and let the caller take care of it.
13044        if (restarting) {
13045            return;
13046        }
13047
13048        if (!app.persistent || app.isolated) {
13049            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13050                    "Removing non-persistent process during cleanup: " + app);
13051            mProcessNames.remove(app.processName, app.uid);
13052            mIsolatedProcesses.remove(app.uid);
13053            if (mHeavyWeightProcess == app) {
13054                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13055                        mHeavyWeightProcess.userId, 0));
13056                mHeavyWeightProcess = null;
13057            }
13058        } else if (!app.removed) {
13059            // This app is persistent, so we need to keep its record around.
13060            // If it is not already on the pending app list, add it there
13061            // and start a new process for it.
13062            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13063                mPersistentStartingProcesses.add(app);
13064                restart = true;
13065            }
13066        }
13067        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13068                "Clean-up removing on hold: " + app);
13069        mProcessesOnHold.remove(app);
13070
13071        if (app == mHomeProcess) {
13072            mHomeProcess = null;
13073        }
13074        if (app == mPreviousProcess) {
13075            mPreviousProcess = null;
13076        }
13077
13078        if (restart && !app.isolated) {
13079            // We have components that still need to be running in the
13080            // process, so re-launch it.
13081            mProcessNames.put(app.processName, app.uid, app);
13082            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13083        } else if (app.pid > 0 && app.pid != MY_PID) {
13084            // Goodbye!
13085            boolean removed;
13086            synchronized (mPidsSelfLocked) {
13087                mPidsSelfLocked.remove(app.pid);
13088                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13089            }
13090            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13091                    app.processName, app.info.uid);
13092            if (app.isolated) {
13093                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13094            }
13095            app.setPid(0);
13096        }
13097    }
13098
13099    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13100        // Look through the content providers we are waiting to have launched,
13101        // and if any run in this process then either schedule a restart of
13102        // the process or kill the client waiting for it if this process has
13103        // gone bad.
13104        int NL = mLaunchingProviders.size();
13105        boolean restart = false;
13106        for (int i=0; i<NL; i++) {
13107            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13108            if (cpr.launchingApp == app) {
13109                if (!alwaysBad && !app.bad) {
13110                    restart = true;
13111                } else {
13112                    removeDyingProviderLocked(app, cpr, true);
13113                    // cpr should have been removed from mLaunchingProviders
13114                    NL = mLaunchingProviders.size();
13115                    i--;
13116                }
13117            }
13118        }
13119        return restart;
13120    }
13121
13122    // =========================================================
13123    // SERVICES
13124    // =========================================================
13125
13126    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13127            int flags) {
13128        enforceNotIsolatedCaller("getServices");
13129        synchronized (this) {
13130            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13131        }
13132    }
13133
13134    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13135        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13136        synchronized (this) {
13137            return mServices.getRunningServiceControlPanelLocked(name);
13138        }
13139    }
13140
13141    public ComponentName startService(IApplicationThread caller, Intent service,
13142            String resolvedType, int userId) {
13143        enforceNotIsolatedCaller("startService");
13144        // Refuse possible leaked file descriptors
13145        if (service != null && service.hasFileDescriptors() == true) {
13146            throw new IllegalArgumentException("File descriptors passed in Intent");
13147        }
13148
13149        if (DEBUG_SERVICE)
13150            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13151        synchronized(this) {
13152            final int callingPid = Binder.getCallingPid();
13153            final int callingUid = Binder.getCallingUid();
13154            final long origId = Binder.clearCallingIdentity();
13155            ComponentName res = mServices.startServiceLocked(caller, service,
13156                    resolvedType, callingPid, callingUid, userId);
13157            Binder.restoreCallingIdentity(origId);
13158            return res;
13159        }
13160    }
13161
13162    ComponentName startServiceInPackage(int uid,
13163            Intent service, String resolvedType, int userId) {
13164        synchronized(this) {
13165            if (DEBUG_SERVICE)
13166                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13167            final long origId = Binder.clearCallingIdentity();
13168            ComponentName res = mServices.startServiceLocked(null, service,
13169                    resolvedType, -1, uid, userId);
13170            Binder.restoreCallingIdentity(origId);
13171            return res;
13172        }
13173    }
13174
13175    public int stopService(IApplicationThread caller, Intent service,
13176            String resolvedType, int userId) {
13177        enforceNotIsolatedCaller("stopService");
13178        // Refuse possible leaked file descriptors
13179        if (service != null && service.hasFileDescriptors() == true) {
13180            throw new IllegalArgumentException("File descriptors passed in Intent");
13181        }
13182
13183        synchronized(this) {
13184            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13185        }
13186    }
13187
13188    public IBinder peekService(Intent service, String resolvedType) {
13189        enforceNotIsolatedCaller("peekService");
13190        // Refuse possible leaked file descriptors
13191        if (service != null && service.hasFileDescriptors() == true) {
13192            throw new IllegalArgumentException("File descriptors passed in Intent");
13193        }
13194        synchronized(this) {
13195            return mServices.peekServiceLocked(service, resolvedType);
13196        }
13197    }
13198
13199    public boolean stopServiceToken(ComponentName className, IBinder token,
13200            int startId) {
13201        synchronized(this) {
13202            return mServices.stopServiceTokenLocked(className, token, startId);
13203        }
13204    }
13205
13206    public void setServiceForeground(ComponentName className, IBinder token,
13207            int id, Notification notification, boolean removeNotification) {
13208        synchronized(this) {
13209            mServices.setServiceForegroundLocked(className, token, id, notification,
13210                    removeNotification);
13211        }
13212    }
13213
13214    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13215            boolean requireFull, String name, String callerPackage) {
13216        final int callingUserId = UserHandle.getUserId(callingUid);
13217        if (callingUserId != userId) {
13218            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13219                if ((requireFull || checkComponentPermission(
13220                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13221                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13222                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13223                                callingPid, callingUid, -1, true)
13224                                != PackageManager.PERMISSION_GRANTED) {
13225                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13226                        // In this case, they would like to just execute as their
13227                        // owner user instead of failing.
13228                        userId = callingUserId;
13229                    } else {
13230                        StringBuilder builder = new StringBuilder(128);
13231                        builder.append("Permission Denial: ");
13232                        builder.append(name);
13233                        if (callerPackage != null) {
13234                            builder.append(" from ");
13235                            builder.append(callerPackage);
13236                        }
13237                        builder.append(" asks to run as user ");
13238                        builder.append(userId);
13239                        builder.append(" but is calling from user ");
13240                        builder.append(UserHandle.getUserId(callingUid));
13241                        builder.append("; this requires ");
13242                        builder.append(INTERACT_ACROSS_USERS_FULL);
13243                        if (!requireFull) {
13244                            builder.append(" or ");
13245                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13246                        }
13247                        String msg = builder.toString();
13248                        Slog.w(TAG, msg);
13249                        throw new SecurityException(msg);
13250                    }
13251                }
13252            }
13253            if (userId == UserHandle.USER_CURRENT
13254                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13255                // Note that we may be accessing this outside of a lock...
13256                // shouldn't be a big deal, if this is being called outside
13257                // of a locked context there is intrinsically a race with
13258                // the value the caller will receive and someone else changing it.
13259                userId = mCurrentUserId;
13260            }
13261            if (!allowAll && userId < 0) {
13262                throw new IllegalArgumentException(
13263                        "Call does not support special user #" + userId);
13264            }
13265        }
13266        return userId;
13267    }
13268
13269    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13270            String className, int flags) {
13271        boolean result = false;
13272        // For apps that don't have pre-defined UIDs, check for permission
13273        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13274            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13275                if (ActivityManager.checkUidPermission(
13276                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13277                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13278                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13279                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13280                            + " requests FLAG_SINGLE_USER, but app does not hold "
13281                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13282                    Slog.w(TAG, msg);
13283                    throw new SecurityException(msg);
13284                }
13285                // Permission passed
13286                result = true;
13287            }
13288        } else if ("system".equals(componentProcessName)) {
13289            result = true;
13290        } else {
13291            // App with pre-defined UID, check if it's a persistent app
13292            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13293        }
13294        if (DEBUG_MU) {
13295            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13296                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13297        }
13298        return result;
13299    }
13300
13301    /**
13302     * Checks to see if the caller is in the same app as the singleton
13303     * component, or the component is in a special app. It allows special apps
13304     * to export singleton components but prevents exporting singleton
13305     * components for regular apps.
13306     */
13307    boolean isValidSingletonCall(int callingUid, int componentUid) {
13308        int componentAppId = UserHandle.getAppId(componentUid);
13309        return UserHandle.isSameApp(callingUid, componentUid)
13310                || componentAppId == Process.SYSTEM_UID
13311                || componentAppId == Process.PHONE_UID
13312                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13313                        == PackageManager.PERMISSION_GRANTED;
13314    }
13315
13316    public int bindService(IApplicationThread caller, IBinder token,
13317            Intent service, String resolvedType,
13318            IServiceConnection connection, int flags, int userId) {
13319        enforceNotIsolatedCaller("bindService");
13320        // Refuse possible leaked file descriptors
13321        if (service != null && service.hasFileDescriptors() == true) {
13322            throw new IllegalArgumentException("File descriptors passed in Intent");
13323        }
13324
13325        synchronized(this) {
13326            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13327                    connection, flags, userId);
13328        }
13329    }
13330
13331    public boolean unbindService(IServiceConnection connection) {
13332        synchronized (this) {
13333            return mServices.unbindServiceLocked(connection);
13334        }
13335    }
13336
13337    public void publishService(IBinder token, Intent intent, IBinder service) {
13338        // Refuse possible leaked file descriptors
13339        if (intent != null && intent.hasFileDescriptors() == true) {
13340            throw new IllegalArgumentException("File descriptors passed in Intent");
13341        }
13342
13343        synchronized(this) {
13344            if (!(token instanceof ServiceRecord)) {
13345                throw new IllegalArgumentException("Invalid service token");
13346            }
13347            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13348        }
13349    }
13350
13351    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13352        // Refuse possible leaked file descriptors
13353        if (intent != null && intent.hasFileDescriptors() == true) {
13354            throw new IllegalArgumentException("File descriptors passed in Intent");
13355        }
13356
13357        synchronized(this) {
13358            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13359        }
13360    }
13361
13362    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13363        synchronized(this) {
13364            if (!(token instanceof ServiceRecord)) {
13365                throw new IllegalArgumentException("Invalid service token");
13366            }
13367            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13368        }
13369    }
13370
13371    // =========================================================
13372    // BACKUP AND RESTORE
13373    // =========================================================
13374
13375    // Cause the target app to be launched if necessary and its backup agent
13376    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13377    // activity manager to announce its creation.
13378    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13379        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13380        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13381
13382        synchronized(this) {
13383            // !!! TODO: currently no check here that we're already bound
13384            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13385            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13386            synchronized (stats) {
13387                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13388            }
13389
13390            // Backup agent is now in use, its package can't be stopped.
13391            try {
13392                AppGlobals.getPackageManager().setPackageStoppedState(
13393                        app.packageName, false, UserHandle.getUserId(app.uid));
13394            } catch (RemoteException e) {
13395            } catch (IllegalArgumentException e) {
13396                Slog.w(TAG, "Failed trying to unstop package "
13397                        + app.packageName + ": " + e);
13398            }
13399
13400            BackupRecord r = new BackupRecord(ss, app, backupMode);
13401            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13402                    ? new ComponentName(app.packageName, app.backupAgentName)
13403                    : new ComponentName("android", "FullBackupAgent");
13404            // startProcessLocked() returns existing proc's record if it's already running
13405            ProcessRecord proc = startProcessLocked(app.processName, app,
13406                    false, 0, "backup", hostingName, false, false, false);
13407            if (proc == null) {
13408                Slog.e(TAG, "Unable to start backup agent process " + r);
13409                return false;
13410            }
13411
13412            r.app = proc;
13413            mBackupTarget = r;
13414            mBackupAppName = app.packageName;
13415
13416            // Try not to kill the process during backup
13417            updateOomAdjLocked(proc);
13418
13419            // If the process is already attached, schedule the creation of the backup agent now.
13420            // If it is not yet live, this will be done when it attaches to the framework.
13421            if (proc.thread != null) {
13422                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13423                try {
13424                    proc.thread.scheduleCreateBackupAgent(app,
13425                            compatibilityInfoForPackageLocked(app), backupMode);
13426                } catch (RemoteException e) {
13427                    // Will time out on the backup manager side
13428                }
13429            } else {
13430                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13431            }
13432            // Invariants: at this point, the target app process exists and the application
13433            // is either already running or in the process of coming up.  mBackupTarget and
13434            // mBackupAppName describe the app, so that when it binds back to the AM we
13435            // know that it's scheduled for a backup-agent operation.
13436        }
13437
13438        return true;
13439    }
13440
13441    @Override
13442    public void clearPendingBackup() {
13443        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13444        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13445
13446        synchronized (this) {
13447            mBackupTarget = null;
13448            mBackupAppName = null;
13449        }
13450    }
13451
13452    // A backup agent has just come up
13453    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13454        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13455                + " = " + agent);
13456
13457        synchronized(this) {
13458            if (!agentPackageName.equals(mBackupAppName)) {
13459                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13460                return;
13461            }
13462        }
13463
13464        long oldIdent = Binder.clearCallingIdentity();
13465        try {
13466            IBackupManager bm = IBackupManager.Stub.asInterface(
13467                    ServiceManager.getService(Context.BACKUP_SERVICE));
13468            bm.agentConnected(agentPackageName, agent);
13469        } catch (RemoteException e) {
13470            // can't happen; the backup manager service is local
13471        } catch (Exception e) {
13472            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13473            e.printStackTrace();
13474        } finally {
13475            Binder.restoreCallingIdentity(oldIdent);
13476        }
13477    }
13478
13479    // done with this agent
13480    public void unbindBackupAgent(ApplicationInfo appInfo) {
13481        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13482        if (appInfo == null) {
13483            Slog.w(TAG, "unbind backup agent for null app");
13484            return;
13485        }
13486
13487        synchronized(this) {
13488            try {
13489                if (mBackupAppName == null) {
13490                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13491                    return;
13492                }
13493
13494                if (!mBackupAppName.equals(appInfo.packageName)) {
13495                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13496                    return;
13497                }
13498
13499                // Not backing this app up any more; reset its OOM adjustment
13500                final ProcessRecord proc = mBackupTarget.app;
13501                updateOomAdjLocked(proc);
13502
13503                // If the app crashed during backup, 'thread' will be null here
13504                if (proc.thread != null) {
13505                    try {
13506                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13507                                compatibilityInfoForPackageLocked(appInfo));
13508                    } catch (Exception e) {
13509                        Slog.e(TAG, "Exception when unbinding backup agent:");
13510                        e.printStackTrace();
13511                    }
13512                }
13513            } finally {
13514                mBackupTarget = null;
13515                mBackupAppName = null;
13516            }
13517        }
13518    }
13519    // =========================================================
13520    // BROADCASTS
13521    // =========================================================
13522
13523    private final List getStickiesLocked(String action, IntentFilter filter,
13524            List cur, int userId) {
13525        final ContentResolver resolver = mContext.getContentResolver();
13526        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13527        if (stickies == null) {
13528            return cur;
13529        }
13530        final ArrayList<Intent> list = stickies.get(action);
13531        if (list == null) {
13532            return cur;
13533        }
13534        int N = list.size();
13535        for (int i=0; i<N; i++) {
13536            Intent intent = list.get(i);
13537            if (filter.match(resolver, intent, true, TAG) >= 0) {
13538                if (cur == null) {
13539                    cur = new ArrayList<Intent>();
13540                }
13541                cur.add(intent);
13542            }
13543        }
13544        return cur;
13545    }
13546
13547    boolean isPendingBroadcastProcessLocked(int pid) {
13548        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13549                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13550    }
13551
13552    void skipPendingBroadcastLocked(int pid) {
13553            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13554            for (BroadcastQueue queue : mBroadcastQueues) {
13555                queue.skipPendingBroadcastLocked(pid);
13556            }
13557    }
13558
13559    // The app just attached; send any pending broadcasts that it should receive
13560    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13561        boolean didSomething = false;
13562        for (BroadcastQueue queue : mBroadcastQueues) {
13563            didSomething |= queue.sendPendingBroadcastsLocked(app);
13564        }
13565        return didSomething;
13566    }
13567
13568    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13569            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13570        enforceNotIsolatedCaller("registerReceiver");
13571        int callingUid;
13572        int callingPid;
13573        synchronized(this) {
13574            ProcessRecord callerApp = null;
13575            if (caller != null) {
13576                callerApp = getRecordForAppLocked(caller);
13577                if (callerApp == null) {
13578                    throw new SecurityException(
13579                            "Unable to find app for caller " + caller
13580                            + " (pid=" + Binder.getCallingPid()
13581                            + ") when registering receiver " + receiver);
13582                }
13583                if (callerApp.info.uid != Process.SYSTEM_UID &&
13584                        !callerApp.pkgList.containsKey(callerPackage) &&
13585                        !"android".equals(callerPackage)) {
13586                    throw new SecurityException("Given caller package " + callerPackage
13587                            + " is not running in process " + callerApp);
13588                }
13589                callingUid = callerApp.info.uid;
13590                callingPid = callerApp.pid;
13591            } else {
13592                callerPackage = null;
13593                callingUid = Binder.getCallingUid();
13594                callingPid = Binder.getCallingPid();
13595            }
13596
13597            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13598                    true, true, "registerReceiver", callerPackage);
13599
13600            List allSticky = null;
13601
13602            // Look for any matching sticky broadcasts...
13603            Iterator actions = filter.actionsIterator();
13604            if (actions != null) {
13605                while (actions.hasNext()) {
13606                    String action = (String)actions.next();
13607                    allSticky = getStickiesLocked(action, filter, allSticky,
13608                            UserHandle.USER_ALL);
13609                    allSticky = getStickiesLocked(action, filter, allSticky,
13610                            UserHandle.getUserId(callingUid));
13611                }
13612            } else {
13613                allSticky = getStickiesLocked(null, filter, allSticky,
13614                        UserHandle.USER_ALL);
13615                allSticky = getStickiesLocked(null, filter, allSticky,
13616                        UserHandle.getUserId(callingUid));
13617            }
13618
13619            // The first sticky in the list is returned directly back to
13620            // the client.
13621            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13622
13623            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13624                    + ": " + sticky);
13625
13626            if (receiver == null) {
13627                return sticky;
13628            }
13629
13630            ReceiverList rl
13631                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13632            if (rl == null) {
13633                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13634                        userId, receiver);
13635                if (rl.app != null) {
13636                    rl.app.receivers.add(rl);
13637                } else {
13638                    try {
13639                        receiver.asBinder().linkToDeath(rl, 0);
13640                    } catch (RemoteException e) {
13641                        return sticky;
13642                    }
13643                    rl.linkedToDeath = true;
13644                }
13645                mRegisteredReceivers.put(receiver.asBinder(), rl);
13646            } else if (rl.uid != callingUid) {
13647                throw new IllegalArgumentException(
13648                        "Receiver requested to register for uid " + callingUid
13649                        + " was previously registered for uid " + rl.uid);
13650            } else if (rl.pid != callingPid) {
13651                throw new IllegalArgumentException(
13652                        "Receiver requested to register for pid " + callingPid
13653                        + " was previously registered for pid " + rl.pid);
13654            } else if (rl.userId != userId) {
13655                throw new IllegalArgumentException(
13656                        "Receiver requested to register for user " + userId
13657                        + " was previously registered for user " + rl.userId);
13658            }
13659            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13660                    permission, callingUid, userId);
13661            rl.add(bf);
13662            if (!bf.debugCheck()) {
13663                Slog.w(TAG, "==> For Dynamic broadast");
13664            }
13665            mReceiverResolver.addFilter(bf);
13666
13667            // Enqueue broadcasts for all existing stickies that match
13668            // this filter.
13669            if (allSticky != null) {
13670                ArrayList receivers = new ArrayList();
13671                receivers.add(bf);
13672
13673                int N = allSticky.size();
13674                for (int i=0; i<N; i++) {
13675                    Intent intent = (Intent)allSticky.get(i);
13676                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13677                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13678                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13679                            null, null, false, true, true, -1);
13680                    queue.enqueueParallelBroadcastLocked(r);
13681                    queue.scheduleBroadcastsLocked();
13682                }
13683            }
13684
13685            return sticky;
13686        }
13687    }
13688
13689    public void unregisterReceiver(IIntentReceiver receiver) {
13690        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13691
13692        final long origId = Binder.clearCallingIdentity();
13693        try {
13694            boolean doTrim = false;
13695
13696            synchronized(this) {
13697                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13698                if (rl != null) {
13699                    if (rl.curBroadcast != null) {
13700                        BroadcastRecord r = rl.curBroadcast;
13701                        final boolean doNext = finishReceiverLocked(
13702                                receiver.asBinder(), r.resultCode, r.resultData,
13703                                r.resultExtras, r.resultAbort);
13704                        if (doNext) {
13705                            doTrim = true;
13706                            r.queue.processNextBroadcast(false);
13707                        }
13708                    }
13709
13710                    if (rl.app != null) {
13711                        rl.app.receivers.remove(rl);
13712                    }
13713                    removeReceiverLocked(rl);
13714                    if (rl.linkedToDeath) {
13715                        rl.linkedToDeath = false;
13716                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13717                    }
13718                }
13719            }
13720
13721            // If we actually concluded any broadcasts, we might now be able
13722            // to trim the recipients' apps from our working set
13723            if (doTrim) {
13724                trimApplications();
13725                return;
13726            }
13727
13728        } finally {
13729            Binder.restoreCallingIdentity(origId);
13730        }
13731    }
13732
13733    void removeReceiverLocked(ReceiverList rl) {
13734        mRegisteredReceivers.remove(rl.receiver.asBinder());
13735        int N = rl.size();
13736        for (int i=0; i<N; i++) {
13737            mReceiverResolver.removeFilter(rl.get(i));
13738        }
13739    }
13740
13741    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13742        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13743            ProcessRecord r = mLruProcesses.get(i);
13744            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13745                try {
13746                    r.thread.dispatchPackageBroadcast(cmd, packages);
13747                } catch (RemoteException ex) {
13748                }
13749            }
13750        }
13751    }
13752
13753    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13754            int[] users) {
13755        List<ResolveInfo> receivers = null;
13756        try {
13757            HashSet<ComponentName> singleUserReceivers = null;
13758            boolean scannedFirstReceivers = false;
13759            for (int user : users) {
13760                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13761                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13762                if (user != 0 && newReceivers != null) {
13763                    // If this is not the primary user, we need to check for
13764                    // any receivers that should be filtered out.
13765                    for (int i=0; i<newReceivers.size(); i++) {
13766                        ResolveInfo ri = newReceivers.get(i);
13767                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13768                            newReceivers.remove(i);
13769                            i--;
13770                        }
13771                    }
13772                }
13773                if (newReceivers != null && newReceivers.size() == 0) {
13774                    newReceivers = null;
13775                }
13776                if (receivers == null) {
13777                    receivers = newReceivers;
13778                } else if (newReceivers != null) {
13779                    // We need to concatenate the additional receivers
13780                    // found with what we have do far.  This would be easy,
13781                    // but we also need to de-dup any receivers that are
13782                    // singleUser.
13783                    if (!scannedFirstReceivers) {
13784                        // Collect any single user receivers we had already retrieved.
13785                        scannedFirstReceivers = true;
13786                        for (int i=0; i<receivers.size(); i++) {
13787                            ResolveInfo ri = receivers.get(i);
13788                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13789                                ComponentName cn = new ComponentName(
13790                                        ri.activityInfo.packageName, ri.activityInfo.name);
13791                                if (singleUserReceivers == null) {
13792                                    singleUserReceivers = new HashSet<ComponentName>();
13793                                }
13794                                singleUserReceivers.add(cn);
13795                            }
13796                        }
13797                    }
13798                    // Add the new results to the existing results, tracking
13799                    // and de-dupping single user receivers.
13800                    for (int i=0; i<newReceivers.size(); i++) {
13801                        ResolveInfo ri = newReceivers.get(i);
13802                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13803                            ComponentName cn = new ComponentName(
13804                                    ri.activityInfo.packageName, ri.activityInfo.name);
13805                            if (singleUserReceivers == null) {
13806                                singleUserReceivers = new HashSet<ComponentName>();
13807                            }
13808                            if (!singleUserReceivers.contains(cn)) {
13809                                singleUserReceivers.add(cn);
13810                                receivers.add(ri);
13811                            }
13812                        } else {
13813                            receivers.add(ri);
13814                        }
13815                    }
13816                }
13817            }
13818        } catch (RemoteException ex) {
13819            // pm is in same process, this will never happen.
13820        }
13821        return receivers;
13822    }
13823
13824    private final int broadcastIntentLocked(ProcessRecord callerApp,
13825            String callerPackage, Intent intent, String resolvedType,
13826            IIntentReceiver resultTo, int resultCode, String resultData,
13827            Bundle map, String requiredPermission, int appOp,
13828            boolean ordered, boolean sticky, int callingPid, int callingUid,
13829            int userId) {
13830        intent = new Intent(intent);
13831
13832        // By default broadcasts do not go to stopped apps.
13833        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13834
13835        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13836            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13837            + " ordered=" + ordered + " userid=" + userId);
13838        if ((resultTo != null) && !ordered) {
13839            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13840        }
13841
13842        userId = handleIncomingUser(callingPid, callingUid, userId,
13843                true, false, "broadcast", callerPackage);
13844
13845        // Make sure that the user who is receiving this broadcast is started.
13846        // If not, we will just skip it.
13847        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13848            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13849                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13850                Slog.w(TAG, "Skipping broadcast of " + intent
13851                        + ": user " + userId + " is stopped");
13852                return ActivityManager.BROADCAST_SUCCESS;
13853            }
13854        }
13855
13856        /*
13857         * Prevent non-system code (defined here to be non-persistent
13858         * processes) from sending protected broadcasts.
13859         */
13860        int callingAppId = UserHandle.getAppId(callingUid);
13861        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13862                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13863                || callingUid == 0) {
13864            // Always okay.
13865        } else if (callerApp == null || !callerApp.persistent) {
13866            try {
13867                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13868                        intent.getAction())) {
13869                    String msg = "Permission Denial: not allowed to send broadcast "
13870                            + intent.getAction() + " from pid="
13871                            + callingPid + ", uid=" + callingUid;
13872                    Slog.w(TAG, msg);
13873                    throw new SecurityException(msg);
13874                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13875                    // Special case for compatibility: we don't want apps to send this,
13876                    // but historically it has not been protected and apps may be using it
13877                    // to poke their own app widget.  So, instead of making it protected,
13878                    // just limit it to the caller.
13879                    if (callerApp == null) {
13880                        String msg = "Permission Denial: not allowed to send broadcast "
13881                                + intent.getAction() + " from unknown caller.";
13882                        Slog.w(TAG, msg);
13883                        throw new SecurityException(msg);
13884                    } else if (intent.getComponent() != null) {
13885                        // They are good enough to send to an explicit component...  verify
13886                        // it is being sent to the calling app.
13887                        if (!intent.getComponent().getPackageName().equals(
13888                                callerApp.info.packageName)) {
13889                            String msg = "Permission Denial: not allowed to send broadcast "
13890                                    + intent.getAction() + " to "
13891                                    + intent.getComponent().getPackageName() + " from "
13892                                    + callerApp.info.packageName;
13893                            Slog.w(TAG, msg);
13894                            throw new SecurityException(msg);
13895                        }
13896                    } else {
13897                        // Limit broadcast to their own package.
13898                        intent.setPackage(callerApp.info.packageName);
13899                    }
13900                }
13901            } catch (RemoteException e) {
13902                Slog.w(TAG, "Remote exception", e);
13903                return ActivityManager.BROADCAST_SUCCESS;
13904            }
13905        }
13906
13907        // Handle special intents: if this broadcast is from the package
13908        // manager about a package being removed, we need to remove all of
13909        // its activities from the history stack.
13910        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13911                intent.getAction());
13912        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13913                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13914                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13915                || uidRemoved) {
13916            if (checkComponentPermission(
13917                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13918                    callingPid, callingUid, -1, true)
13919                    == PackageManager.PERMISSION_GRANTED) {
13920                if (uidRemoved) {
13921                    final Bundle intentExtras = intent.getExtras();
13922                    final int uid = intentExtras != null
13923                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13924                    if (uid >= 0) {
13925                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13926                        synchronized (bs) {
13927                            bs.removeUidStatsLocked(uid);
13928                        }
13929                        mAppOpsService.uidRemoved(uid);
13930                    }
13931                } else {
13932                    // If resources are unavailable just force stop all
13933                    // those packages and flush the attribute cache as well.
13934                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13935                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13936                        if (list != null && (list.length > 0)) {
13937                            for (String pkg : list) {
13938                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13939                                        "storage unmount");
13940                            }
13941                            sendPackageBroadcastLocked(
13942                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13943                        }
13944                    } else {
13945                        Uri data = intent.getData();
13946                        String ssp;
13947                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13948                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13949                                    intent.getAction());
13950                            boolean fullUninstall = removed &&
13951                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13952                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13953                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13954                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13955                                        false, fullUninstall, userId,
13956                                        removed ? "pkg removed" : "pkg changed");
13957                            }
13958                            if (removed) {
13959                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13960                                        new String[] {ssp}, userId);
13961                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13962                                    mAppOpsService.packageRemoved(
13963                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13964
13965                                    // Remove all permissions granted from/to this package
13966                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13967                                }
13968                            }
13969                        }
13970                    }
13971                }
13972            } else {
13973                String msg = "Permission Denial: " + intent.getAction()
13974                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13975                        + ", uid=" + callingUid + ")"
13976                        + " requires "
13977                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13978                Slog.w(TAG, msg);
13979                throw new SecurityException(msg);
13980            }
13981
13982        // Special case for adding a package: by default turn on compatibility
13983        // mode.
13984        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13985            Uri data = intent.getData();
13986            String ssp;
13987            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13988                mCompatModePackages.handlePackageAddedLocked(ssp,
13989                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13990            }
13991        }
13992
13993        /*
13994         * If this is the time zone changed action, queue up a message that will reset the timezone
13995         * of all currently running processes. This message will get queued up before the broadcast
13996         * happens.
13997         */
13998        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13999            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14000        }
14001
14002        /*
14003         * If the user set the time, let all running processes know.
14004         */
14005        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14006            final int is24Hour = intent.getBooleanExtra(
14007                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14008            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14009        }
14010
14011        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14012            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14013        }
14014
14015        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14016            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14017            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14018        }
14019
14020        // Add to the sticky list if requested.
14021        if (sticky) {
14022            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14023                    callingPid, callingUid)
14024                    != PackageManager.PERMISSION_GRANTED) {
14025                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14026                        + callingPid + ", uid=" + callingUid
14027                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14028                Slog.w(TAG, msg);
14029                throw new SecurityException(msg);
14030            }
14031            if (requiredPermission != null) {
14032                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14033                        + " and enforce permission " + requiredPermission);
14034                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14035            }
14036            if (intent.getComponent() != null) {
14037                throw new SecurityException(
14038                        "Sticky broadcasts can't target a specific component");
14039            }
14040            // We use userId directly here, since the "all" target is maintained
14041            // as a separate set of sticky broadcasts.
14042            if (userId != UserHandle.USER_ALL) {
14043                // But first, if this is not a broadcast to all users, then
14044                // make sure it doesn't conflict with an existing broadcast to
14045                // all users.
14046                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14047                        UserHandle.USER_ALL);
14048                if (stickies != null) {
14049                    ArrayList<Intent> list = stickies.get(intent.getAction());
14050                    if (list != null) {
14051                        int N = list.size();
14052                        int i;
14053                        for (i=0; i<N; i++) {
14054                            if (intent.filterEquals(list.get(i))) {
14055                                throw new IllegalArgumentException(
14056                                        "Sticky broadcast " + intent + " for user "
14057                                        + userId + " conflicts with existing global broadcast");
14058                            }
14059                        }
14060                    }
14061                }
14062            }
14063            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14064            if (stickies == null) {
14065                stickies = new ArrayMap<String, ArrayList<Intent>>();
14066                mStickyBroadcasts.put(userId, stickies);
14067            }
14068            ArrayList<Intent> list = stickies.get(intent.getAction());
14069            if (list == null) {
14070                list = new ArrayList<Intent>();
14071                stickies.put(intent.getAction(), list);
14072            }
14073            int N = list.size();
14074            int i;
14075            for (i=0; i<N; i++) {
14076                if (intent.filterEquals(list.get(i))) {
14077                    // This sticky already exists, replace it.
14078                    list.set(i, new Intent(intent));
14079                    break;
14080                }
14081            }
14082            if (i >= N) {
14083                list.add(new Intent(intent));
14084            }
14085        }
14086
14087        int[] users;
14088        if (userId == UserHandle.USER_ALL) {
14089            // Caller wants broadcast to go to all started users.
14090            users = mStartedUserArray;
14091        } else {
14092            // Caller wants broadcast to go to one specific user.
14093            users = new int[] {userId};
14094        }
14095
14096        // Figure out who all will receive this broadcast.
14097        List receivers = null;
14098        List<BroadcastFilter> registeredReceivers = null;
14099        // Need to resolve the intent to interested receivers...
14100        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14101                 == 0) {
14102            receivers = collectReceiverComponents(intent, resolvedType, users);
14103        }
14104        if (intent.getComponent() == null) {
14105            registeredReceivers = mReceiverResolver.queryIntent(intent,
14106                    resolvedType, false, userId);
14107        }
14108
14109        final boolean replacePending =
14110                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14111
14112        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14113                + " replacePending=" + replacePending);
14114
14115        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14116        if (!ordered && NR > 0) {
14117            // If we are not serializing this broadcast, then send the
14118            // registered receivers separately so they don't wait for the
14119            // components to be launched.
14120            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14121            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14122                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14123                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14124                    ordered, sticky, false, userId);
14125            if (DEBUG_BROADCAST) Slog.v(
14126                    TAG, "Enqueueing parallel broadcast " + r);
14127            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14128            if (!replaced) {
14129                queue.enqueueParallelBroadcastLocked(r);
14130                queue.scheduleBroadcastsLocked();
14131            }
14132            registeredReceivers = null;
14133            NR = 0;
14134        }
14135
14136        // Merge into one list.
14137        int ir = 0;
14138        if (receivers != null) {
14139            // A special case for PACKAGE_ADDED: do not allow the package
14140            // being added to see this broadcast.  This prevents them from
14141            // using this as a back door to get run as soon as they are
14142            // installed.  Maybe in the future we want to have a special install
14143            // broadcast or such for apps, but we'd like to deliberately make
14144            // this decision.
14145            String skipPackages[] = null;
14146            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14147                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14148                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14149                Uri data = intent.getData();
14150                if (data != null) {
14151                    String pkgName = data.getSchemeSpecificPart();
14152                    if (pkgName != null) {
14153                        skipPackages = new String[] { pkgName };
14154                    }
14155                }
14156            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14157                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14158            }
14159            if (skipPackages != null && (skipPackages.length > 0)) {
14160                for (String skipPackage : skipPackages) {
14161                    if (skipPackage != null) {
14162                        int NT = receivers.size();
14163                        for (int it=0; it<NT; it++) {
14164                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14165                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14166                                receivers.remove(it);
14167                                it--;
14168                                NT--;
14169                            }
14170                        }
14171                    }
14172                }
14173            }
14174
14175            int NT = receivers != null ? receivers.size() : 0;
14176            int it = 0;
14177            ResolveInfo curt = null;
14178            BroadcastFilter curr = null;
14179            while (it < NT && ir < NR) {
14180                if (curt == null) {
14181                    curt = (ResolveInfo)receivers.get(it);
14182                }
14183                if (curr == null) {
14184                    curr = registeredReceivers.get(ir);
14185                }
14186                if (curr.getPriority() >= curt.priority) {
14187                    // Insert this broadcast record into the final list.
14188                    receivers.add(it, curr);
14189                    ir++;
14190                    curr = null;
14191                    it++;
14192                    NT++;
14193                } else {
14194                    // Skip to the next ResolveInfo in the final list.
14195                    it++;
14196                    curt = null;
14197                }
14198            }
14199        }
14200        while (ir < NR) {
14201            if (receivers == null) {
14202                receivers = new ArrayList();
14203            }
14204            receivers.add(registeredReceivers.get(ir));
14205            ir++;
14206        }
14207
14208        if ((receivers != null && receivers.size() > 0)
14209                || resultTo != null) {
14210            BroadcastQueue queue = broadcastQueueForIntent(intent);
14211            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14212                    callerPackage, callingPid, callingUid, resolvedType,
14213                    requiredPermission, appOp, receivers, resultTo, resultCode,
14214                    resultData, map, ordered, sticky, false, userId);
14215            if (DEBUG_BROADCAST) Slog.v(
14216                    TAG, "Enqueueing ordered broadcast " + r
14217                    + ": prev had " + queue.mOrderedBroadcasts.size());
14218            if (DEBUG_BROADCAST) {
14219                int seq = r.intent.getIntExtra("seq", -1);
14220                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14221            }
14222            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14223            if (!replaced) {
14224                queue.enqueueOrderedBroadcastLocked(r);
14225                queue.scheduleBroadcastsLocked();
14226            }
14227        }
14228
14229        return ActivityManager.BROADCAST_SUCCESS;
14230    }
14231
14232    final Intent verifyBroadcastLocked(Intent intent) {
14233        // Refuse possible leaked file descriptors
14234        if (intent != null && intent.hasFileDescriptors() == true) {
14235            throw new IllegalArgumentException("File descriptors passed in Intent");
14236        }
14237
14238        int flags = intent.getFlags();
14239
14240        if (!mProcessesReady) {
14241            // if the caller really truly claims to know what they're doing, go
14242            // ahead and allow the broadcast without launching any receivers
14243            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14244                intent = new Intent(intent);
14245                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14246            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14247                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14248                        + " before boot completion");
14249                throw new IllegalStateException("Cannot broadcast before boot completed");
14250            }
14251        }
14252
14253        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14254            throw new IllegalArgumentException(
14255                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14256        }
14257
14258        return intent;
14259    }
14260
14261    public final int broadcastIntent(IApplicationThread caller,
14262            Intent intent, String resolvedType, IIntentReceiver resultTo,
14263            int resultCode, String resultData, Bundle map,
14264            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14265        enforceNotIsolatedCaller("broadcastIntent");
14266        synchronized(this) {
14267            intent = verifyBroadcastLocked(intent);
14268
14269            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14270            final int callingPid = Binder.getCallingPid();
14271            final int callingUid = Binder.getCallingUid();
14272            final long origId = Binder.clearCallingIdentity();
14273            int res = broadcastIntentLocked(callerApp,
14274                    callerApp != null ? callerApp.info.packageName : null,
14275                    intent, resolvedType, resultTo,
14276                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14277                    callingPid, callingUid, userId);
14278            Binder.restoreCallingIdentity(origId);
14279            return res;
14280        }
14281    }
14282
14283    int broadcastIntentInPackage(String packageName, int uid,
14284            Intent intent, String resolvedType, IIntentReceiver resultTo,
14285            int resultCode, String resultData, Bundle map,
14286            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14287        synchronized(this) {
14288            intent = verifyBroadcastLocked(intent);
14289
14290            final long origId = Binder.clearCallingIdentity();
14291            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14292                    resultTo, resultCode, resultData, map, requiredPermission,
14293                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14294            Binder.restoreCallingIdentity(origId);
14295            return res;
14296        }
14297    }
14298
14299    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14300        // Refuse possible leaked file descriptors
14301        if (intent != null && intent.hasFileDescriptors() == true) {
14302            throw new IllegalArgumentException("File descriptors passed in Intent");
14303        }
14304
14305        userId = handleIncomingUser(Binder.getCallingPid(),
14306                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14307
14308        synchronized(this) {
14309            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14310                    != PackageManager.PERMISSION_GRANTED) {
14311                String msg = "Permission Denial: unbroadcastIntent() from pid="
14312                        + Binder.getCallingPid()
14313                        + ", uid=" + Binder.getCallingUid()
14314                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14315                Slog.w(TAG, msg);
14316                throw new SecurityException(msg);
14317            }
14318            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14319            if (stickies != null) {
14320                ArrayList<Intent> list = stickies.get(intent.getAction());
14321                if (list != null) {
14322                    int N = list.size();
14323                    int i;
14324                    for (i=0; i<N; i++) {
14325                        if (intent.filterEquals(list.get(i))) {
14326                            list.remove(i);
14327                            break;
14328                        }
14329                    }
14330                    if (list.size() <= 0) {
14331                        stickies.remove(intent.getAction());
14332                    }
14333                }
14334                if (stickies.size() <= 0) {
14335                    mStickyBroadcasts.remove(userId);
14336                }
14337            }
14338        }
14339    }
14340
14341    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14342            String resultData, Bundle resultExtras, boolean resultAbort) {
14343        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14344        if (r == null) {
14345            Slog.w(TAG, "finishReceiver called but not found on queue");
14346            return false;
14347        }
14348
14349        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14350    }
14351
14352    void backgroundServicesFinishedLocked(int userId) {
14353        for (BroadcastQueue queue : mBroadcastQueues) {
14354            queue.backgroundServicesFinishedLocked(userId);
14355        }
14356    }
14357
14358    public void finishReceiver(IBinder who, int resultCode, String resultData,
14359            Bundle resultExtras, boolean resultAbort) {
14360        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14361
14362        // Refuse possible leaked file descriptors
14363        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14364            throw new IllegalArgumentException("File descriptors passed in Bundle");
14365        }
14366
14367        final long origId = Binder.clearCallingIdentity();
14368        try {
14369            boolean doNext = false;
14370            BroadcastRecord r;
14371
14372            synchronized(this) {
14373                r = broadcastRecordForReceiverLocked(who);
14374                if (r != null) {
14375                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14376                        resultData, resultExtras, resultAbort, true);
14377                }
14378            }
14379
14380            if (doNext) {
14381                r.queue.processNextBroadcast(false);
14382            }
14383            trimApplications();
14384        } finally {
14385            Binder.restoreCallingIdentity(origId);
14386        }
14387    }
14388
14389    // =========================================================
14390    // INSTRUMENTATION
14391    // =========================================================
14392
14393    public boolean startInstrumentation(ComponentName className,
14394            String profileFile, int flags, Bundle arguments,
14395            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14396            int userId, String abiOverride) {
14397        enforceNotIsolatedCaller("startInstrumentation");
14398        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14399                userId, false, true, "startInstrumentation", null);
14400        // Refuse possible leaked file descriptors
14401        if (arguments != null && arguments.hasFileDescriptors()) {
14402            throw new IllegalArgumentException("File descriptors passed in Bundle");
14403        }
14404
14405        synchronized(this) {
14406            InstrumentationInfo ii = null;
14407            ApplicationInfo ai = null;
14408            try {
14409                ii = mContext.getPackageManager().getInstrumentationInfo(
14410                    className, STOCK_PM_FLAGS);
14411                ai = AppGlobals.getPackageManager().getApplicationInfo(
14412                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14413            } catch (PackageManager.NameNotFoundException e) {
14414            } catch (RemoteException e) {
14415            }
14416            if (ii == null) {
14417                reportStartInstrumentationFailure(watcher, className,
14418                        "Unable to find instrumentation info for: " + className);
14419                return false;
14420            }
14421            if (ai == null) {
14422                reportStartInstrumentationFailure(watcher, className,
14423                        "Unable to find instrumentation target package: " + ii.targetPackage);
14424                return false;
14425            }
14426
14427            int match = mContext.getPackageManager().checkSignatures(
14428                    ii.targetPackage, ii.packageName);
14429            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14430                String msg = "Permission Denial: starting instrumentation "
14431                        + className + " from pid="
14432                        + Binder.getCallingPid()
14433                        + ", uid=" + Binder.getCallingPid()
14434                        + " not allowed because package " + ii.packageName
14435                        + " does not have a signature matching the target "
14436                        + ii.targetPackage;
14437                reportStartInstrumentationFailure(watcher, className, msg);
14438                throw new SecurityException(msg);
14439            }
14440
14441            final long origId = Binder.clearCallingIdentity();
14442            // Instrumentation can kill and relaunch even persistent processes
14443            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14444                    "start instr");
14445            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14446            app.instrumentationClass = className;
14447            app.instrumentationInfo = ai;
14448            app.instrumentationProfileFile = profileFile;
14449            app.instrumentationArguments = arguments;
14450            app.instrumentationWatcher = watcher;
14451            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14452            app.instrumentationResultClass = className;
14453            Binder.restoreCallingIdentity(origId);
14454        }
14455
14456        return true;
14457    }
14458
14459    /**
14460     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14461     * error to the logs, but if somebody is watching, send the report there too.  This enables
14462     * the "am" command to report errors with more information.
14463     *
14464     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14465     * @param cn The component name of the instrumentation.
14466     * @param report The error report.
14467     */
14468    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14469            ComponentName cn, String report) {
14470        Slog.w(TAG, report);
14471        try {
14472            if (watcher != null) {
14473                Bundle results = new Bundle();
14474                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14475                results.putString("Error", report);
14476                watcher.instrumentationStatus(cn, -1, results);
14477            }
14478        } catch (RemoteException e) {
14479            Slog.w(TAG, e);
14480        }
14481    }
14482
14483    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14484        if (app.instrumentationWatcher != null) {
14485            try {
14486                // NOTE:  IInstrumentationWatcher *must* be oneway here
14487                app.instrumentationWatcher.instrumentationFinished(
14488                    app.instrumentationClass,
14489                    resultCode,
14490                    results);
14491            } catch (RemoteException e) {
14492            }
14493        }
14494        if (app.instrumentationUiAutomationConnection != null) {
14495            try {
14496                app.instrumentationUiAutomationConnection.shutdown();
14497            } catch (RemoteException re) {
14498                /* ignore */
14499            }
14500            // Only a UiAutomation can set this flag and now that
14501            // it is finished we make sure it is reset to its default.
14502            mUserIsMonkey = false;
14503        }
14504        app.instrumentationWatcher = null;
14505        app.instrumentationUiAutomationConnection = null;
14506        app.instrumentationClass = null;
14507        app.instrumentationInfo = null;
14508        app.instrumentationProfileFile = null;
14509        app.instrumentationArguments = null;
14510
14511        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14512                "finished inst");
14513    }
14514
14515    public void finishInstrumentation(IApplicationThread target,
14516            int resultCode, Bundle results) {
14517        int userId = UserHandle.getCallingUserId();
14518        // Refuse possible leaked file descriptors
14519        if (results != null && results.hasFileDescriptors()) {
14520            throw new IllegalArgumentException("File descriptors passed in Intent");
14521        }
14522
14523        synchronized(this) {
14524            ProcessRecord app = getRecordForAppLocked(target);
14525            if (app == null) {
14526                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14527                return;
14528            }
14529            final long origId = Binder.clearCallingIdentity();
14530            finishInstrumentationLocked(app, resultCode, results);
14531            Binder.restoreCallingIdentity(origId);
14532        }
14533    }
14534
14535    // =========================================================
14536    // CONFIGURATION
14537    // =========================================================
14538
14539    public ConfigurationInfo getDeviceConfigurationInfo() {
14540        ConfigurationInfo config = new ConfigurationInfo();
14541        synchronized (this) {
14542            config.reqTouchScreen = mConfiguration.touchscreen;
14543            config.reqKeyboardType = mConfiguration.keyboard;
14544            config.reqNavigation = mConfiguration.navigation;
14545            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14546                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14547                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14548            }
14549            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14550                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14551                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14552            }
14553            config.reqGlEsVersion = GL_ES_VERSION;
14554        }
14555        return config;
14556    }
14557
14558    ActivityStack getFocusedStack() {
14559        return mStackSupervisor.getFocusedStack();
14560    }
14561
14562    public Configuration getConfiguration() {
14563        Configuration ci;
14564        synchronized(this) {
14565            ci = new Configuration(mConfiguration);
14566        }
14567        return ci;
14568    }
14569
14570    public void updatePersistentConfiguration(Configuration values) {
14571        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14572                "updateConfiguration()");
14573        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14574                "updateConfiguration()");
14575        if (values == null) {
14576            throw new NullPointerException("Configuration must not be null");
14577        }
14578
14579        synchronized(this) {
14580            final long origId = Binder.clearCallingIdentity();
14581            updateConfigurationLocked(values, null, true, false);
14582            Binder.restoreCallingIdentity(origId);
14583        }
14584    }
14585
14586    public void updateConfiguration(Configuration values) {
14587        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14588                "updateConfiguration()");
14589
14590        synchronized(this) {
14591            if (values == null && mWindowManager != null) {
14592                // sentinel: fetch the current configuration from the window manager
14593                values = mWindowManager.computeNewConfiguration();
14594            }
14595
14596            if (mWindowManager != null) {
14597                mProcessList.applyDisplaySize(mWindowManager);
14598            }
14599
14600            final long origId = Binder.clearCallingIdentity();
14601            if (values != null) {
14602                Settings.System.clearConfiguration(values);
14603            }
14604            updateConfigurationLocked(values, null, false, false);
14605            Binder.restoreCallingIdentity(origId);
14606        }
14607    }
14608
14609    /**
14610     * Do either or both things: (1) change the current configuration, and (2)
14611     * make sure the given activity is running with the (now) current
14612     * configuration.  Returns true if the activity has been left running, or
14613     * false if <var>starting</var> is being destroyed to match the new
14614     * configuration.
14615     * @param persistent TODO
14616     */
14617    boolean updateConfigurationLocked(Configuration values,
14618            ActivityRecord starting, boolean persistent, boolean initLocale) {
14619        int changes = 0;
14620
14621        if (values != null) {
14622            Configuration newConfig = new Configuration(mConfiguration);
14623            changes = newConfig.updateFrom(values);
14624            if (changes != 0) {
14625                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14626                    Slog.i(TAG, "Updating configuration to: " + values);
14627                }
14628
14629                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14630
14631                if (values.locale != null && !initLocale) {
14632                    saveLocaleLocked(values.locale,
14633                                     !values.locale.equals(mConfiguration.locale),
14634                                     values.userSetLocale);
14635                }
14636
14637                mConfigurationSeq++;
14638                if (mConfigurationSeq <= 0) {
14639                    mConfigurationSeq = 1;
14640                }
14641                newConfig.seq = mConfigurationSeq;
14642                mConfiguration = newConfig;
14643                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14644                mUsageStatsService.noteStartConfig(newConfig);
14645
14646                final Configuration configCopy = new Configuration(mConfiguration);
14647
14648                // TODO: If our config changes, should we auto dismiss any currently
14649                // showing dialogs?
14650                mShowDialogs = shouldShowDialogs(newConfig);
14651
14652                AttributeCache ac = AttributeCache.instance();
14653                if (ac != null) {
14654                    ac.updateConfiguration(configCopy);
14655                }
14656
14657                // Make sure all resources in our process are updated
14658                // right now, so that anyone who is going to retrieve
14659                // resource values after we return will be sure to get
14660                // the new ones.  This is especially important during
14661                // boot, where the first config change needs to guarantee
14662                // all resources have that config before following boot
14663                // code is executed.
14664                mSystemThread.applyConfigurationToResources(configCopy);
14665
14666                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14667                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14668                    msg.obj = new Configuration(configCopy);
14669                    mHandler.sendMessage(msg);
14670                }
14671
14672                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14673                    ProcessRecord app = mLruProcesses.get(i);
14674                    try {
14675                        if (app.thread != null) {
14676                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14677                                    + app.processName + " new config " + mConfiguration);
14678                            app.thread.scheduleConfigurationChanged(configCopy);
14679                        }
14680                    } catch (Exception e) {
14681                    }
14682                }
14683                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14684                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14685                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14686                        | Intent.FLAG_RECEIVER_FOREGROUND);
14687                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14688                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14689                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14690                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14691                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14692                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14693                    broadcastIntentLocked(null, null, intent,
14694                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14695                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14696                }
14697            }
14698        }
14699
14700        boolean kept = true;
14701        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14702        // mainStack is null during startup.
14703        if (mainStack != null) {
14704            if (changes != 0 && starting == null) {
14705                // If the configuration changed, and the caller is not already
14706                // in the process of starting an activity, then find the top
14707                // activity to check if its configuration needs to change.
14708                starting = mainStack.topRunningActivityLocked(null);
14709            }
14710
14711            if (starting != null) {
14712                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14713                // And we need to make sure at this point that all other activities
14714                // are made visible with the correct configuration.
14715                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14716            }
14717        }
14718
14719        if (values != null && mWindowManager != null) {
14720            mWindowManager.setNewConfiguration(mConfiguration);
14721        }
14722
14723        return kept;
14724    }
14725
14726    /**
14727     * Decide based on the configuration whether we should shouw the ANR,
14728     * crash, etc dialogs.  The idea is that if there is no affordnace to
14729     * press the on-screen buttons, we shouldn't show the dialog.
14730     *
14731     * A thought: SystemUI might also want to get told about this, the Power
14732     * dialog / global actions also might want different behaviors.
14733     */
14734    private static final boolean shouldShowDialogs(Configuration config) {
14735        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14736                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14737    }
14738
14739    /**
14740     * Save the locale.  You must be inside a synchronized (this) block.
14741     */
14742    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14743        if(isDiff) {
14744            SystemProperties.set("user.language", l.getLanguage());
14745            SystemProperties.set("user.region", l.getCountry());
14746        }
14747
14748        if(isPersist) {
14749            SystemProperties.set("persist.sys.language", l.getLanguage());
14750            SystemProperties.set("persist.sys.country", l.getCountry());
14751            SystemProperties.set("persist.sys.localevar", l.getVariant());
14752        }
14753    }
14754
14755    @Override
14756    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14757        ActivityRecord srec = ActivityRecord.forToken(token);
14758        return srec != null && srec.task.affinity != null &&
14759                srec.task.affinity.equals(destAffinity);
14760    }
14761
14762    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14763            Intent resultData) {
14764
14765        synchronized (this) {
14766            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14767            if (stack != null) {
14768                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14769            }
14770            return false;
14771        }
14772    }
14773
14774    public int getLaunchedFromUid(IBinder activityToken) {
14775        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14776        if (srec == null) {
14777            return -1;
14778        }
14779        return srec.launchedFromUid;
14780    }
14781
14782    public String getLaunchedFromPackage(IBinder activityToken) {
14783        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14784        if (srec == null) {
14785            return null;
14786        }
14787        return srec.launchedFromPackage;
14788    }
14789
14790    // =========================================================
14791    // LIFETIME MANAGEMENT
14792    // =========================================================
14793
14794    // Returns which broadcast queue the app is the current [or imminent] receiver
14795    // on, or 'null' if the app is not an active broadcast recipient.
14796    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14797        BroadcastRecord r = app.curReceiver;
14798        if (r != null) {
14799            return r.queue;
14800        }
14801
14802        // It's not the current receiver, but it might be starting up to become one
14803        synchronized (this) {
14804            for (BroadcastQueue queue : mBroadcastQueues) {
14805                r = queue.mPendingBroadcast;
14806                if (r != null && r.curApp == app) {
14807                    // found it; report which queue it's in
14808                    return queue;
14809                }
14810            }
14811        }
14812
14813        return null;
14814    }
14815
14816    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14817            boolean doingAll, long now) {
14818        if (mAdjSeq == app.adjSeq) {
14819            // This adjustment has already been computed.
14820            return app.curRawAdj;
14821        }
14822
14823        if (app.thread == null) {
14824            app.adjSeq = mAdjSeq;
14825            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14826            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14827            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14828        }
14829
14830        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14831        app.adjSource = null;
14832        app.adjTarget = null;
14833        app.empty = false;
14834        app.cached = false;
14835
14836        final int activitiesSize = app.activities.size();
14837
14838        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14839            // The max adjustment doesn't allow this app to be anything
14840            // below foreground, so it is not worth doing work for it.
14841            app.adjType = "fixed";
14842            app.adjSeq = mAdjSeq;
14843            app.curRawAdj = app.maxAdj;
14844            app.foregroundActivities = false;
14845            app.keeping = true;
14846            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14847            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14848            // System processes can do UI, and when they do we want to have
14849            // them trim their memory after the user leaves the UI.  To
14850            // facilitate this, here we need to determine whether or not it
14851            // is currently showing UI.
14852            app.systemNoUi = true;
14853            if (app == TOP_APP) {
14854                app.systemNoUi = false;
14855            } else if (activitiesSize > 0) {
14856                for (int j = 0; j < activitiesSize; j++) {
14857                    final ActivityRecord r = app.activities.get(j);
14858                    if (r.visible) {
14859                        app.systemNoUi = false;
14860                    }
14861                }
14862            }
14863            if (!app.systemNoUi) {
14864                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14865            }
14866            return (app.curAdj=app.maxAdj);
14867        }
14868
14869        app.keeping = false;
14870        app.systemNoUi = false;
14871
14872        // Determine the importance of the process, starting with most
14873        // important to least, and assign an appropriate OOM adjustment.
14874        int adj;
14875        int schedGroup;
14876        int procState;
14877        boolean foregroundActivities = false;
14878        boolean interesting = false;
14879        BroadcastQueue queue;
14880        if (app == TOP_APP) {
14881            // The last app on the list is the foreground app.
14882            adj = ProcessList.FOREGROUND_APP_ADJ;
14883            schedGroup = Process.THREAD_GROUP_DEFAULT;
14884            app.adjType = "top-activity";
14885            foregroundActivities = true;
14886            interesting = true;
14887            procState = ActivityManager.PROCESS_STATE_TOP;
14888        } else if (app.instrumentationClass != null) {
14889            // Don't want to kill running instrumentation.
14890            adj = ProcessList.FOREGROUND_APP_ADJ;
14891            schedGroup = Process.THREAD_GROUP_DEFAULT;
14892            app.adjType = "instrumentation";
14893            interesting = true;
14894            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14895        } else if ((queue = isReceivingBroadcast(app)) != null) {
14896            // An app that is currently receiving a broadcast also
14897            // counts as being in the foreground for OOM killer purposes.
14898            // It's placed in a sched group based on the nature of the
14899            // broadcast as reflected by which queue it's active in.
14900            adj = ProcessList.FOREGROUND_APP_ADJ;
14901            schedGroup = (queue == mFgBroadcastQueue)
14902                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14903            app.adjType = "broadcast";
14904            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14905        } else if (app.executingServices.size() > 0) {
14906            // An app that is currently executing a service callback also
14907            // counts as being in the foreground.
14908            adj = ProcessList.FOREGROUND_APP_ADJ;
14909            schedGroup = app.execServicesFg ?
14910                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14911            app.adjType = "exec-service";
14912            procState = ActivityManager.PROCESS_STATE_SERVICE;
14913            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14914        } else {
14915            // As far as we know the process is empty.  We may change our mind later.
14916            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14917            // At this point we don't actually know the adjustment.  Use the cached adj
14918            // value that the caller wants us to.
14919            adj = cachedAdj;
14920            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14921            app.cached = true;
14922            app.empty = true;
14923            app.adjType = "cch-empty";
14924        }
14925
14926        // Examine all activities if not already foreground.
14927        if (!foregroundActivities && activitiesSize > 0) {
14928            for (int j = 0; j < activitiesSize; j++) {
14929                final ActivityRecord r = app.activities.get(j);
14930                if (r.app != app) {
14931                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14932                            + app + "?!?");
14933                    continue;
14934                }
14935                if (r.visible) {
14936                    // App has a visible activity; only upgrade adjustment.
14937                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14938                        adj = ProcessList.VISIBLE_APP_ADJ;
14939                        app.adjType = "visible";
14940                    }
14941                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14942                        procState = ActivityManager.PROCESS_STATE_TOP;
14943                    }
14944                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14945                    app.cached = false;
14946                    app.empty = false;
14947                    foregroundActivities = true;
14948                    break;
14949                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14950                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14951                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14952                        app.adjType = "pausing";
14953                    }
14954                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14955                        procState = ActivityManager.PROCESS_STATE_TOP;
14956                    }
14957                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14958                    app.cached = false;
14959                    app.empty = false;
14960                    foregroundActivities = true;
14961                } else if (r.state == ActivityState.STOPPING) {
14962                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14963                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14964                        app.adjType = "stopping";
14965                    }
14966                    // For the process state, we will at this point consider the
14967                    // process to be cached.  It will be cached either as an activity
14968                    // or empty depending on whether the activity is finishing.  We do
14969                    // this so that we can treat the process as cached for purposes of
14970                    // memory trimming (determing current memory level, trim command to
14971                    // send to process) since there can be an arbitrary number of stopping
14972                    // processes and they should soon all go into the cached state.
14973                    if (!r.finishing) {
14974                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14975                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14976                        }
14977                    }
14978                    app.cached = false;
14979                    app.empty = false;
14980                    foregroundActivities = true;
14981                } else {
14982                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14983                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14984                        app.adjType = "cch-act";
14985                    }
14986                }
14987            }
14988        }
14989
14990        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14991            if (app.foregroundServices) {
14992                // The user is aware of this app, so make it visible.
14993                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14994                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14995                app.cached = false;
14996                app.adjType = "fg-service";
14997                schedGroup = Process.THREAD_GROUP_DEFAULT;
14998            } else if (app.forcingToForeground != null) {
14999                // The user is aware of this app, so make it visible.
15000                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15001                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15002                app.cached = false;
15003                app.adjType = "force-fg";
15004                app.adjSource = app.forcingToForeground;
15005                schedGroup = Process.THREAD_GROUP_DEFAULT;
15006            }
15007        }
15008
15009        if (app.foregroundServices) {
15010            interesting = true;
15011        }
15012
15013        if (app == mHeavyWeightProcess) {
15014            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15015                // We don't want to kill the current heavy-weight process.
15016                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15017                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15018                app.cached = false;
15019                app.adjType = "heavy";
15020            }
15021            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15022                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15023            }
15024        }
15025
15026        if (app == mHomeProcess) {
15027            if (adj > ProcessList.HOME_APP_ADJ) {
15028                // This process is hosting what we currently consider to be the
15029                // home app, so we don't want to let it go into the background.
15030                adj = ProcessList.HOME_APP_ADJ;
15031                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15032                app.cached = false;
15033                app.adjType = "home";
15034            }
15035            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15036                procState = ActivityManager.PROCESS_STATE_HOME;
15037            }
15038        }
15039
15040        if (app == mPreviousProcess && app.activities.size() > 0) {
15041            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15042                // This was the previous process that showed UI to the user.
15043                // We want to try to keep it around more aggressively, to give
15044                // a good experience around switching between two apps.
15045                adj = ProcessList.PREVIOUS_APP_ADJ;
15046                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15047                app.cached = false;
15048                app.adjType = "previous";
15049            }
15050            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15051                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15052            }
15053        }
15054
15055        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15056                + " reason=" + app.adjType);
15057
15058        // By default, we use the computed adjustment.  It may be changed if
15059        // there are applications dependent on our services or providers, but
15060        // this gives us a baseline and makes sure we don't get into an
15061        // infinite recursion.
15062        app.adjSeq = mAdjSeq;
15063        app.curRawAdj = adj;
15064        app.hasStartedServices = false;
15065
15066        if (mBackupTarget != null && app == mBackupTarget.app) {
15067            // If possible we want to avoid killing apps while they're being backed up
15068            if (adj > ProcessList.BACKUP_APP_ADJ) {
15069                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15070                adj = ProcessList.BACKUP_APP_ADJ;
15071                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15072                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15073                }
15074                app.adjType = "backup";
15075                app.cached = false;
15076            }
15077            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15078                procState = ActivityManager.PROCESS_STATE_BACKUP;
15079            }
15080        }
15081
15082        boolean mayBeTop = false;
15083
15084        for (int is = app.services.size()-1;
15085                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15086                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15087                        || procState > ActivityManager.PROCESS_STATE_TOP);
15088                is--) {
15089            ServiceRecord s = app.services.valueAt(is);
15090            if (s.startRequested) {
15091                app.hasStartedServices = true;
15092                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15093                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15094                }
15095                if (app.hasShownUi && app != mHomeProcess) {
15096                    // If this process has shown some UI, let it immediately
15097                    // go to the LRU list because it may be pretty heavy with
15098                    // UI stuff.  We'll tag it with a label just to help
15099                    // debug and understand what is going on.
15100                    if (adj > ProcessList.SERVICE_ADJ) {
15101                        app.adjType = "cch-started-ui-services";
15102                    }
15103                } else {
15104                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15105                        // This service has seen some activity within
15106                        // recent memory, so we will keep its process ahead
15107                        // of the background processes.
15108                        if (adj > ProcessList.SERVICE_ADJ) {
15109                            adj = ProcessList.SERVICE_ADJ;
15110                            app.adjType = "started-services";
15111                            app.cached = false;
15112                        }
15113                    }
15114                    // If we have let the service slide into the background
15115                    // state, still have some text describing what it is doing
15116                    // even though the service no longer has an impact.
15117                    if (adj > ProcessList.SERVICE_ADJ) {
15118                        app.adjType = "cch-started-services";
15119                    }
15120                }
15121                // Don't kill this process because it is doing work; it
15122                // has said it is doing work.
15123                app.keeping = true;
15124            }
15125            for (int conni = s.connections.size()-1;
15126                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15127                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15128                            || procState > ActivityManager.PROCESS_STATE_TOP);
15129                    conni--) {
15130                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15131                for (int i = 0;
15132                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15133                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15134                                || procState > ActivityManager.PROCESS_STATE_TOP);
15135                        i++) {
15136                    // XXX should compute this based on the max of
15137                    // all connected clients.
15138                    ConnectionRecord cr = clist.get(i);
15139                    if (cr.binding.client == app) {
15140                        // Binding to ourself is not interesting.
15141                        continue;
15142                    }
15143                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15144                        ProcessRecord client = cr.binding.client;
15145                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15146                                TOP_APP, doingAll, now);
15147                        int clientProcState = client.curProcState;
15148                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15149                            // If the other app is cached for any reason, for purposes here
15150                            // we are going to consider it empty.  The specific cached state
15151                            // doesn't propagate except under certain conditions.
15152                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15153                        }
15154                        String adjType = null;
15155                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15156                            // Not doing bind OOM management, so treat
15157                            // this guy more like a started service.
15158                            if (app.hasShownUi && app != mHomeProcess) {
15159                                // If this process has shown some UI, let it immediately
15160                                // go to the LRU list because it may be pretty heavy with
15161                                // UI stuff.  We'll tag it with a label just to help
15162                                // debug and understand what is going on.
15163                                if (adj > clientAdj) {
15164                                    adjType = "cch-bound-ui-services";
15165                                }
15166                                app.cached = false;
15167                                clientAdj = adj;
15168                                clientProcState = procState;
15169                            } else {
15170                                if (now >= (s.lastActivity
15171                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15172                                    // This service has not seen activity within
15173                                    // recent memory, so allow it to drop to the
15174                                    // LRU list if there is no other reason to keep
15175                                    // it around.  We'll also tag it with a label just
15176                                    // to help debug and undertand what is going on.
15177                                    if (adj > clientAdj) {
15178                                        adjType = "cch-bound-services";
15179                                    }
15180                                    clientAdj = adj;
15181                                }
15182                            }
15183                        }
15184                        if (adj > clientAdj) {
15185                            // If this process has recently shown UI, and
15186                            // the process that is binding to it is less
15187                            // important than being visible, then we don't
15188                            // care about the binding as much as we care
15189                            // about letting this process get into the LRU
15190                            // list to be killed and restarted if needed for
15191                            // memory.
15192                            if (app.hasShownUi && app != mHomeProcess
15193                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15194                                adjType = "cch-bound-ui-services";
15195                            } else {
15196                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15197                                        |Context.BIND_IMPORTANT)) != 0) {
15198                                    adj = clientAdj;
15199                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15200                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15201                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15202                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15203                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15204                                    adj = clientAdj;
15205                                } else {
15206                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15207                                        adj = ProcessList.VISIBLE_APP_ADJ;
15208                                    }
15209                                }
15210                                if (!client.cached) {
15211                                    app.cached = false;
15212                                }
15213                                if (client.keeping) {
15214                                    app.keeping = true;
15215                                }
15216                                adjType = "service";
15217                            }
15218                        }
15219                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15220                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15221                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15222                            }
15223                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15224                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15225                                    // Special handling of clients who are in the top state.
15226                                    // We *may* want to consider this process to be in the
15227                                    // top state as well, but only if there is not another
15228                                    // reason for it to be running.  Being on the top is a
15229                                    // special state, meaning you are specifically running
15230                                    // for the current top app.  If the process is already
15231                                    // running in the background for some other reason, it
15232                                    // is more important to continue considering it to be
15233                                    // in the background state.
15234                                    mayBeTop = true;
15235                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15236                                } else {
15237                                    // Special handling for above-top states (persistent
15238                                    // processes).  These should not bring the current process
15239                                    // into the top state, since they are not on top.  Instead
15240                                    // give them the best state after that.
15241                                    clientProcState =
15242                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15243                                }
15244                            }
15245                        } else {
15246                            if (clientProcState <
15247                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15248                                clientProcState =
15249                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15250                            }
15251                        }
15252                        if (procState > clientProcState) {
15253                            procState = clientProcState;
15254                        }
15255                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15256                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15257                            app.pendingUiClean = true;
15258                        }
15259                        if (adjType != null) {
15260                            app.adjType = adjType;
15261                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15262                                    .REASON_SERVICE_IN_USE;
15263                            app.adjSource = cr.binding.client;
15264                            app.adjSourceOom = clientAdj;
15265                            app.adjTarget = s.name;
15266                        }
15267                    }
15268                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15269                        app.treatLikeActivity = true;
15270                    }
15271                    final ActivityRecord a = cr.activity;
15272                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15273                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15274                                (a.visible || a.state == ActivityState.RESUMED
15275                                 || a.state == ActivityState.PAUSING)) {
15276                            adj = ProcessList.FOREGROUND_APP_ADJ;
15277                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15278                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15279                            }
15280                            app.cached = false;
15281                            app.adjType = "service";
15282                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15283                                    .REASON_SERVICE_IN_USE;
15284                            app.adjSource = a;
15285                            app.adjSourceOom = adj;
15286                            app.adjTarget = s.name;
15287                        }
15288                    }
15289                }
15290            }
15291        }
15292
15293        for (int provi = app.pubProviders.size()-1;
15294                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15295                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15296                        || procState > ActivityManager.PROCESS_STATE_TOP);
15297                provi--) {
15298            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15299            for (int i = cpr.connections.size()-1;
15300                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15301                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15302                            || procState > ActivityManager.PROCESS_STATE_TOP);
15303                    i--) {
15304                ContentProviderConnection conn = cpr.connections.get(i);
15305                ProcessRecord client = conn.client;
15306                if (client == app) {
15307                    // Being our own client is not interesting.
15308                    continue;
15309                }
15310                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15311                int clientProcState = client.curProcState;
15312                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15313                    // If the other app is cached for any reason, for purposes here
15314                    // we are going to consider it empty.
15315                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15316                }
15317                if (adj > clientAdj) {
15318                    if (app.hasShownUi && app != mHomeProcess
15319                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15320                        app.adjType = "cch-ui-provider";
15321                    } else {
15322                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15323                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15324                        app.adjType = "provider";
15325                    }
15326                    app.cached &= client.cached;
15327                    app.keeping |= client.keeping;
15328                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15329                            .REASON_PROVIDER_IN_USE;
15330                    app.adjSource = client;
15331                    app.adjSourceOom = clientAdj;
15332                    app.adjTarget = cpr.name;
15333                }
15334                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15335                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15336                        // Special handling of clients who are in the top state.
15337                        // We *may* want to consider this process to be in the
15338                        // top state as well, but only if there is not another
15339                        // reason for it to be running.  Being on the top is a
15340                        // special state, meaning you are specifically running
15341                        // for the current top app.  If the process is already
15342                        // running in the background for some other reason, it
15343                        // is more important to continue considering it to be
15344                        // in the background state.
15345                        mayBeTop = true;
15346                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15347                    } else {
15348                        // Special handling for above-top states (persistent
15349                        // processes).  These should not bring the current process
15350                        // into the top state, since they are not on top.  Instead
15351                        // give them the best state after that.
15352                        clientProcState =
15353                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15354                    }
15355                }
15356                if (procState > clientProcState) {
15357                    procState = clientProcState;
15358                }
15359                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15360                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15361                }
15362            }
15363            // If the provider has external (non-framework) process
15364            // dependencies, ensure that its adjustment is at least
15365            // FOREGROUND_APP_ADJ.
15366            if (cpr.hasExternalProcessHandles()) {
15367                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15368                    adj = ProcessList.FOREGROUND_APP_ADJ;
15369                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15370                    app.cached = false;
15371                    app.keeping = true;
15372                    app.adjType = "provider";
15373                    app.adjTarget = cpr.name;
15374                }
15375                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15376                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15377                }
15378            }
15379        }
15380
15381        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15382            // A client of one of our services or providers is in the top state.  We
15383            // *may* want to be in the top state, but not if we are already running in
15384            // the background for some other reason.  For the decision here, we are going
15385            // to pick out a few specific states that we want to remain in when a client
15386            // is top (states that tend to be longer-term) and otherwise allow it to go
15387            // to the top state.
15388            switch (procState) {
15389                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15390                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15391                case ActivityManager.PROCESS_STATE_SERVICE:
15392                    // These all are longer-term states, so pull them up to the top
15393                    // of the background states, but not all the way to the top state.
15394                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15395                    break;
15396                default:
15397                    // Otherwise, top is a better choice, so take it.
15398                    procState = ActivityManager.PROCESS_STATE_TOP;
15399                    break;
15400            }
15401        }
15402
15403        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15404            if (app.hasClientActivities) {
15405                // This is a cached process, but with client activities.  Mark it so.
15406                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15407                app.adjType = "cch-client-act";
15408            } else if (app.treatLikeActivity) {
15409                // This is a cached process, but somebody wants us to treat it like it has
15410                // an activity, okay!
15411                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15412                app.adjType = "cch-as-act";
15413            }
15414        }
15415
15416        if (adj == ProcessList.SERVICE_ADJ) {
15417            if (doingAll) {
15418                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15419                mNewNumServiceProcs++;
15420                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15421                if (!app.serviceb) {
15422                    // This service isn't far enough down on the LRU list to
15423                    // normally be a B service, but if we are low on RAM and it
15424                    // is large we want to force it down since we would prefer to
15425                    // keep launcher over it.
15426                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15427                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15428                        app.serviceHighRam = true;
15429                        app.serviceb = true;
15430                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15431                    } else {
15432                        mNewNumAServiceProcs++;
15433                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15434                    }
15435                } else {
15436                    app.serviceHighRam = false;
15437                }
15438            }
15439            if (app.serviceb) {
15440                adj = ProcessList.SERVICE_B_ADJ;
15441            }
15442        }
15443
15444        app.curRawAdj = adj;
15445
15446        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15447        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15448        if (adj > app.maxAdj) {
15449            adj = app.maxAdj;
15450            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15451                schedGroup = Process.THREAD_GROUP_DEFAULT;
15452            }
15453        }
15454        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15455            app.keeping = true;
15456        }
15457
15458        // Do final modification to adj.  Everything we do between here and applying
15459        // the final setAdj must be done in this function, because we will also use
15460        // it when computing the final cached adj later.  Note that we don't need to
15461        // worry about this for max adj above, since max adj will always be used to
15462        // keep it out of the cached vaues.
15463        app.curAdj = app.modifyRawOomAdj(adj);
15464        app.curSchedGroup = schedGroup;
15465        app.curProcState = procState;
15466        app.foregroundActivities = foregroundActivities;
15467
15468        return app.curRawAdj;
15469    }
15470
15471    /**
15472     * Schedule PSS collection of a process.
15473     */
15474    void requestPssLocked(ProcessRecord proc, int procState) {
15475        if (mPendingPssProcesses.contains(proc)) {
15476            return;
15477        }
15478        if (mPendingPssProcesses.size() == 0) {
15479            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15480        }
15481        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15482        proc.pssProcState = procState;
15483        mPendingPssProcesses.add(proc);
15484    }
15485
15486    /**
15487     * Schedule PSS collection of all processes.
15488     */
15489    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15490        if (!always) {
15491            if (now < (mLastFullPssTime +
15492                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15493                return;
15494            }
15495        }
15496        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15497        mLastFullPssTime = now;
15498        mFullPssPending = true;
15499        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15500        mPendingPssProcesses.clear();
15501        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15502            ProcessRecord app = mLruProcesses.get(i);
15503            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15504                app.pssProcState = app.setProcState;
15505                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15506                        isSleeping(), now);
15507                mPendingPssProcesses.add(app);
15508            }
15509        }
15510        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15511    }
15512
15513    /**
15514     * Ask a given process to GC right now.
15515     */
15516    final void performAppGcLocked(ProcessRecord app) {
15517        try {
15518            app.lastRequestedGc = SystemClock.uptimeMillis();
15519            if (app.thread != null) {
15520                if (app.reportLowMemory) {
15521                    app.reportLowMemory = false;
15522                    app.thread.scheduleLowMemory();
15523                } else {
15524                    app.thread.processInBackground();
15525                }
15526            }
15527        } catch (Exception e) {
15528            // whatever.
15529        }
15530    }
15531
15532    /**
15533     * Returns true if things are idle enough to perform GCs.
15534     */
15535    private final boolean canGcNowLocked() {
15536        boolean processingBroadcasts = false;
15537        for (BroadcastQueue q : mBroadcastQueues) {
15538            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15539                processingBroadcasts = true;
15540            }
15541        }
15542        return !processingBroadcasts
15543                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15544    }
15545
15546    /**
15547     * Perform GCs on all processes that are waiting for it, but only
15548     * if things are idle.
15549     */
15550    final void performAppGcsLocked() {
15551        final int N = mProcessesToGc.size();
15552        if (N <= 0) {
15553            return;
15554        }
15555        if (canGcNowLocked()) {
15556            while (mProcessesToGc.size() > 0) {
15557                ProcessRecord proc = mProcessesToGc.remove(0);
15558                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15559                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15560                            <= SystemClock.uptimeMillis()) {
15561                        // To avoid spamming the system, we will GC processes one
15562                        // at a time, waiting a few seconds between each.
15563                        performAppGcLocked(proc);
15564                        scheduleAppGcsLocked();
15565                        return;
15566                    } else {
15567                        // It hasn't been long enough since we last GCed this
15568                        // process...  put it in the list to wait for its time.
15569                        addProcessToGcListLocked(proc);
15570                        break;
15571                    }
15572                }
15573            }
15574
15575            scheduleAppGcsLocked();
15576        }
15577    }
15578
15579    /**
15580     * If all looks good, perform GCs on all processes waiting for them.
15581     */
15582    final void performAppGcsIfAppropriateLocked() {
15583        if (canGcNowLocked()) {
15584            performAppGcsLocked();
15585            return;
15586        }
15587        // Still not idle, wait some more.
15588        scheduleAppGcsLocked();
15589    }
15590
15591    /**
15592     * Schedule the execution of all pending app GCs.
15593     */
15594    final void scheduleAppGcsLocked() {
15595        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15596
15597        if (mProcessesToGc.size() > 0) {
15598            // Schedule a GC for the time to the next process.
15599            ProcessRecord proc = mProcessesToGc.get(0);
15600            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15601
15602            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15603            long now = SystemClock.uptimeMillis();
15604            if (when < (now+GC_TIMEOUT)) {
15605                when = now + GC_TIMEOUT;
15606            }
15607            mHandler.sendMessageAtTime(msg, when);
15608        }
15609    }
15610
15611    /**
15612     * Add a process to the array of processes waiting to be GCed.  Keeps the
15613     * list in sorted order by the last GC time.  The process can't already be
15614     * on the list.
15615     */
15616    final void addProcessToGcListLocked(ProcessRecord proc) {
15617        boolean added = false;
15618        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15619            if (mProcessesToGc.get(i).lastRequestedGc <
15620                    proc.lastRequestedGc) {
15621                added = true;
15622                mProcessesToGc.add(i+1, proc);
15623                break;
15624            }
15625        }
15626        if (!added) {
15627            mProcessesToGc.add(0, proc);
15628        }
15629    }
15630
15631    /**
15632     * Set up to ask a process to GC itself.  This will either do it
15633     * immediately, or put it on the list of processes to gc the next
15634     * time things are idle.
15635     */
15636    final void scheduleAppGcLocked(ProcessRecord app) {
15637        long now = SystemClock.uptimeMillis();
15638        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15639            return;
15640        }
15641        if (!mProcessesToGc.contains(app)) {
15642            addProcessToGcListLocked(app);
15643            scheduleAppGcsLocked();
15644        }
15645    }
15646
15647    final void checkExcessivePowerUsageLocked(boolean doKills) {
15648        updateCpuStatsNow();
15649
15650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15651        boolean doWakeKills = doKills;
15652        boolean doCpuKills = doKills;
15653        if (mLastPowerCheckRealtime == 0) {
15654            doWakeKills = false;
15655        }
15656        if (mLastPowerCheckUptime == 0) {
15657            doCpuKills = false;
15658        }
15659        if (stats.isScreenOn()) {
15660            doWakeKills = false;
15661        }
15662        final long curRealtime = SystemClock.elapsedRealtime();
15663        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15664        final long curUptime = SystemClock.uptimeMillis();
15665        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15666        mLastPowerCheckRealtime = curRealtime;
15667        mLastPowerCheckUptime = curUptime;
15668        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15669            doWakeKills = false;
15670        }
15671        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15672            doCpuKills = false;
15673        }
15674        int i = mLruProcesses.size();
15675        while (i > 0) {
15676            i--;
15677            ProcessRecord app = mLruProcesses.get(i);
15678            if (!app.keeping) {
15679                long wtime;
15680                synchronized (stats) {
15681                    wtime = stats.getProcessWakeTime(app.info.uid,
15682                            app.pid, curRealtime);
15683                }
15684                long wtimeUsed = wtime - app.lastWakeTime;
15685                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15686                if (DEBUG_POWER) {
15687                    StringBuilder sb = new StringBuilder(128);
15688                    sb.append("Wake for ");
15689                    app.toShortString(sb);
15690                    sb.append(": over ");
15691                    TimeUtils.formatDuration(realtimeSince, sb);
15692                    sb.append(" used ");
15693                    TimeUtils.formatDuration(wtimeUsed, sb);
15694                    sb.append(" (");
15695                    sb.append((wtimeUsed*100)/realtimeSince);
15696                    sb.append("%)");
15697                    Slog.i(TAG, sb.toString());
15698                    sb.setLength(0);
15699                    sb.append("CPU for ");
15700                    app.toShortString(sb);
15701                    sb.append(": over ");
15702                    TimeUtils.formatDuration(uptimeSince, sb);
15703                    sb.append(" used ");
15704                    TimeUtils.formatDuration(cputimeUsed, sb);
15705                    sb.append(" (");
15706                    sb.append((cputimeUsed*100)/uptimeSince);
15707                    sb.append("%)");
15708                    Slog.i(TAG, sb.toString());
15709                }
15710                // If a process has held a wake lock for more
15711                // than 50% of the time during this period,
15712                // that sounds bad.  Kill!
15713                if (doWakeKills && realtimeSince > 0
15714                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15715                    synchronized (stats) {
15716                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15717                                realtimeSince, wtimeUsed);
15718                    }
15719                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15720                            + " during " + realtimeSince);
15721                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15722                } else if (doCpuKills && uptimeSince > 0
15723                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15724                    synchronized (stats) {
15725                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15726                                uptimeSince, cputimeUsed);
15727                    }
15728                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15729                            + " during " + uptimeSince);
15730                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15731                } else {
15732                    app.lastWakeTime = wtime;
15733                    app.lastCpuTime = app.curCpuTime;
15734                }
15735            }
15736        }
15737    }
15738
15739    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15740            ProcessRecord TOP_APP, boolean doingAll, long now) {
15741        boolean success = true;
15742
15743        if (app.curRawAdj != app.setRawAdj) {
15744            if (wasKeeping && !app.keeping) {
15745                // This app is no longer something we want to keep.  Note
15746                // its current wake lock time to later know to kill it if
15747                // it is not behaving well.
15748                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15749                synchronized (stats) {
15750                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15751                            app.pid, SystemClock.elapsedRealtime());
15752                }
15753                app.lastCpuTime = app.curCpuTime;
15754            }
15755
15756            app.setRawAdj = app.curRawAdj;
15757        }
15758
15759        int changes = 0;
15760
15761        if (app.curAdj != app.setAdj) {
15762            ProcessList.setOomAdj(app.pid, app.curAdj);
15763            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15764                TAG, "Set " + app.pid + " " + app.processName +
15765                " adj " + app.curAdj + ": " + app.adjType);
15766            app.setAdj = app.curAdj;
15767        }
15768
15769        if (app.setSchedGroup != app.curSchedGroup) {
15770            app.setSchedGroup = app.curSchedGroup;
15771            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15772                    "Setting process group of " + app.processName
15773                    + " to " + app.curSchedGroup);
15774            if (app.waitingToKill != null &&
15775                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15776                killUnneededProcessLocked(app, app.waitingToKill);
15777                success = false;
15778            } else {
15779                if (true) {
15780                    long oldId = Binder.clearCallingIdentity();
15781                    try {
15782                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15783                    } catch (Exception e) {
15784                        Slog.w(TAG, "Failed setting process group of " + app.pid
15785                                + " to " + app.curSchedGroup);
15786                        e.printStackTrace();
15787                    } finally {
15788                        Binder.restoreCallingIdentity(oldId);
15789                    }
15790                } else {
15791                    if (app.thread != null) {
15792                        try {
15793                            app.thread.setSchedulingGroup(app.curSchedGroup);
15794                        } catch (RemoteException e) {
15795                        }
15796                    }
15797                }
15798                Process.setSwappiness(app.pid,
15799                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15800            }
15801        }
15802        if (app.repForegroundActivities != app.foregroundActivities) {
15803            app.repForegroundActivities = app.foregroundActivities;
15804            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15805        }
15806        if (app.repProcState != app.curProcState) {
15807            app.repProcState = app.curProcState;
15808            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15809            if (app.thread != null) {
15810                try {
15811                    if (false) {
15812                        //RuntimeException h = new RuntimeException("here");
15813                        Slog.i(TAG, "Sending new process state " + app.repProcState
15814                                + " to " + app /*, h*/);
15815                    }
15816                    app.thread.setProcessState(app.repProcState);
15817                } catch (RemoteException e) {
15818                }
15819            }
15820        }
15821        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15822                app.setProcState)) {
15823            app.lastStateTime = now;
15824            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15825                    isSleeping(), now);
15826            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15827                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15828                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15829                    + (app.nextPssTime-now) + ": " + app);
15830        } else {
15831            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15832                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15833                requestPssLocked(app, app.setProcState);
15834                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15835                        isSleeping(), now);
15836            } else if (false && DEBUG_PSS) {
15837                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15838            }
15839        }
15840        if (app.setProcState != app.curProcState) {
15841            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15842                    "Proc state change of " + app.processName
15843                    + " to " + app.curProcState);
15844            app.setProcState = app.curProcState;
15845            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15846                app.notCachedSinceIdle = false;
15847            }
15848            if (!doingAll) {
15849                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15850            } else {
15851                app.procStateChanged = true;
15852            }
15853        }
15854
15855        if (changes != 0) {
15856            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15857            int i = mPendingProcessChanges.size()-1;
15858            ProcessChangeItem item = null;
15859            while (i >= 0) {
15860                item = mPendingProcessChanges.get(i);
15861                if (item.pid == app.pid) {
15862                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15863                    break;
15864                }
15865                i--;
15866            }
15867            if (i < 0) {
15868                // No existing item in pending changes; need a new one.
15869                final int NA = mAvailProcessChanges.size();
15870                if (NA > 0) {
15871                    item = mAvailProcessChanges.remove(NA-1);
15872                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15873                } else {
15874                    item = new ProcessChangeItem();
15875                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15876                }
15877                item.changes = 0;
15878                item.pid = app.pid;
15879                item.uid = app.info.uid;
15880                if (mPendingProcessChanges.size() == 0) {
15881                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15882                            "*** Enqueueing dispatch processes changed!");
15883                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15884                }
15885                mPendingProcessChanges.add(item);
15886            }
15887            item.changes |= changes;
15888            item.processState = app.repProcState;
15889            item.foregroundActivities = app.repForegroundActivities;
15890            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15891                    + Integer.toHexString(System.identityHashCode(item))
15892                    + " " + app.toShortString() + ": changes=" + item.changes
15893                    + " procState=" + item.processState
15894                    + " foreground=" + item.foregroundActivities
15895                    + " type=" + app.adjType + " source=" + app.adjSource
15896                    + " target=" + app.adjTarget);
15897        }
15898
15899        return success;
15900    }
15901
15902    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15903        if (proc.thread != null && proc.baseProcessTracker != null) {
15904            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15905        }
15906    }
15907
15908    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15909            ProcessRecord TOP_APP, boolean doingAll, long now) {
15910        if (app.thread == null) {
15911            return false;
15912        }
15913
15914        final boolean wasKeeping = app.keeping;
15915
15916        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15917
15918        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15919    }
15920
15921    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15922            boolean oomAdj) {
15923        if (isForeground != proc.foregroundServices) {
15924            proc.foregroundServices = isForeground;
15925            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15926                    proc.info.uid);
15927            if (isForeground) {
15928                if (curProcs == null) {
15929                    curProcs = new ArrayList<ProcessRecord>();
15930                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15931                }
15932                if (!curProcs.contains(proc)) {
15933                    curProcs.add(proc);
15934                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15935                            proc.info.packageName, proc.info.uid);
15936                }
15937            } else {
15938                if (curProcs != null) {
15939                    if (curProcs.remove(proc)) {
15940                        mBatteryStatsService.noteEvent(
15941                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15942                                proc.info.packageName, proc.info.uid);
15943                        if (curProcs.size() <= 0) {
15944                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15945                        }
15946                    }
15947                }
15948            }
15949            if (oomAdj) {
15950                updateOomAdjLocked();
15951            }
15952        }
15953    }
15954
15955    private final ActivityRecord resumedAppLocked() {
15956        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15957        String pkg;
15958        int uid;
15959        if (act != null && !act.sleeping) {
15960            pkg = act.packageName;
15961            uid = act.info.applicationInfo.uid;
15962        } else {
15963            pkg = null;
15964            uid = -1;
15965        }
15966        // Has the UID or resumed package name changed?
15967        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15968                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15969            if (mCurResumedPackage != null) {
15970                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15971                        mCurResumedPackage, mCurResumedUid);
15972            }
15973            mCurResumedPackage = pkg;
15974            mCurResumedUid = uid;
15975            if (mCurResumedPackage != null) {
15976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15977                        mCurResumedPackage, mCurResumedUid);
15978            }
15979        }
15980        return act;
15981    }
15982
15983    final boolean updateOomAdjLocked(ProcessRecord app) {
15984        final ActivityRecord TOP_ACT = resumedAppLocked();
15985        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15986        final boolean wasCached = app.cached;
15987
15988        mAdjSeq++;
15989
15990        // This is the desired cached adjusment we want to tell it to use.
15991        // If our app is currently cached, we know it, and that is it.  Otherwise,
15992        // we don't know it yet, and it needs to now be cached we will then
15993        // need to do a complete oom adj.
15994        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15995                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15996        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15997                SystemClock.uptimeMillis());
15998        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15999            // Changed to/from cached state, so apps after it in the LRU
16000            // list may also be changed.
16001            updateOomAdjLocked();
16002        }
16003        return success;
16004    }
16005
16006    final void updateOomAdjLocked() {
16007        final ActivityRecord TOP_ACT = resumedAppLocked();
16008        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16009        final long now = SystemClock.uptimeMillis();
16010        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16011        final int N = mLruProcesses.size();
16012
16013        if (false) {
16014            RuntimeException e = new RuntimeException();
16015            e.fillInStackTrace();
16016            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16017        }
16018
16019        mAdjSeq++;
16020        mNewNumServiceProcs = 0;
16021        mNewNumAServiceProcs = 0;
16022
16023        final int emptyProcessLimit;
16024        final int cachedProcessLimit;
16025        if (mProcessLimit <= 0) {
16026            emptyProcessLimit = cachedProcessLimit = 0;
16027        } else if (mProcessLimit == 1) {
16028            emptyProcessLimit = 1;
16029            cachedProcessLimit = 0;
16030        } else {
16031            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16032            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16033        }
16034
16035        // Let's determine how many processes we have running vs.
16036        // how many slots we have for background processes; we may want
16037        // to put multiple processes in a slot of there are enough of
16038        // them.
16039        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16040                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16041        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16042        if (numEmptyProcs > cachedProcessLimit) {
16043            // If there are more empty processes than our limit on cached
16044            // processes, then use the cached process limit for the factor.
16045            // This ensures that the really old empty processes get pushed
16046            // down to the bottom, so if we are running low on memory we will
16047            // have a better chance at keeping around more cached processes
16048            // instead of a gazillion empty processes.
16049            numEmptyProcs = cachedProcessLimit;
16050        }
16051        int emptyFactor = numEmptyProcs/numSlots;
16052        if (emptyFactor < 1) emptyFactor = 1;
16053        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16054        if (cachedFactor < 1) cachedFactor = 1;
16055        int stepCached = 0;
16056        int stepEmpty = 0;
16057        int numCached = 0;
16058        int numEmpty = 0;
16059        int numTrimming = 0;
16060
16061        mNumNonCachedProcs = 0;
16062        mNumCachedHiddenProcs = 0;
16063
16064        // First update the OOM adjustment for each of the
16065        // application processes based on their current state.
16066        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16067        int nextCachedAdj = curCachedAdj+1;
16068        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16069        int nextEmptyAdj = curEmptyAdj+2;
16070        for (int i=N-1; i>=0; i--) {
16071            ProcessRecord app = mLruProcesses.get(i);
16072            if (!app.killedByAm && app.thread != null) {
16073                app.procStateChanged = false;
16074                final boolean wasKeeping = app.keeping;
16075                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16076
16077                // If we haven't yet assigned the final cached adj
16078                // to the process, do that now.
16079                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16080                    switch (app.curProcState) {
16081                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16082                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16083                            // This process is a cached process holding activities...
16084                            // assign it the next cached value for that type, and then
16085                            // step that cached level.
16086                            app.curRawAdj = curCachedAdj;
16087                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16088                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16089                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16090                                    + ")");
16091                            if (curCachedAdj != nextCachedAdj) {
16092                                stepCached++;
16093                                if (stepCached >= cachedFactor) {
16094                                    stepCached = 0;
16095                                    curCachedAdj = nextCachedAdj;
16096                                    nextCachedAdj += 2;
16097                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16098                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16099                                    }
16100                                }
16101                            }
16102                            break;
16103                        default:
16104                            // For everything else, assign next empty cached process
16105                            // level and bump that up.  Note that this means that
16106                            // long-running services that have dropped down to the
16107                            // cached level will be treated as empty (since their process
16108                            // state is still as a service), which is what we want.
16109                            app.curRawAdj = curEmptyAdj;
16110                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16111                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16112                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16113                                    + ")");
16114                            if (curEmptyAdj != nextEmptyAdj) {
16115                                stepEmpty++;
16116                                if (stepEmpty >= emptyFactor) {
16117                                    stepEmpty = 0;
16118                                    curEmptyAdj = nextEmptyAdj;
16119                                    nextEmptyAdj += 2;
16120                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16121                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16122                                    }
16123                                }
16124                            }
16125                            break;
16126                    }
16127                }
16128
16129                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16130
16131                // Count the number of process types.
16132                switch (app.curProcState) {
16133                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16134                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16135                        mNumCachedHiddenProcs++;
16136                        numCached++;
16137                        if (numCached > cachedProcessLimit) {
16138                            killUnneededProcessLocked(app, "cached #" + numCached);
16139                        }
16140                        break;
16141                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16142                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16143                                && app.lastActivityTime < oldTime) {
16144                            killUnneededProcessLocked(app, "empty for "
16145                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16146                                    / 1000) + "s");
16147                        } else {
16148                            numEmpty++;
16149                            if (numEmpty > emptyProcessLimit) {
16150                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16151                            }
16152                        }
16153                        break;
16154                    default:
16155                        mNumNonCachedProcs++;
16156                        break;
16157                }
16158
16159                if (app.isolated && app.services.size() <= 0) {
16160                    // If this is an isolated process, and there are no
16161                    // services running in it, then the process is no longer
16162                    // needed.  We agressively kill these because we can by
16163                    // definition not re-use the same process again, and it is
16164                    // good to avoid having whatever code was running in them
16165                    // left sitting around after no longer needed.
16166                    killUnneededProcessLocked(app, "isolated not needed");
16167                }
16168
16169                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16170                        && !app.killedByAm) {
16171                    numTrimming++;
16172                }
16173            }
16174        }
16175
16176        mNumServiceProcs = mNewNumServiceProcs;
16177
16178        // Now determine the memory trimming level of background processes.
16179        // Unfortunately we need to start at the back of the list to do this
16180        // properly.  We only do this if the number of background apps we
16181        // are managing to keep around is less than half the maximum we desire;
16182        // if we are keeping a good number around, we'll let them use whatever
16183        // memory they want.
16184        final int numCachedAndEmpty = numCached + numEmpty;
16185        int memFactor;
16186        if (numCached <= ProcessList.TRIM_CACHED_APPS
16187                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16188            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16189                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16190            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16191                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16192            } else {
16193                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16194            }
16195        } else {
16196            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16197        }
16198        // We always allow the memory level to go up (better).  We only allow it to go
16199        // down if we are in a state where that is allowed, *and* the total number of processes
16200        // has gone down since last time.
16201        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16202                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16203                + " last=" + mLastNumProcesses);
16204        if (memFactor > mLastMemoryLevel) {
16205            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16206                memFactor = mLastMemoryLevel;
16207                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16208            }
16209        }
16210        mLastMemoryLevel = memFactor;
16211        mLastNumProcesses = mLruProcesses.size();
16212        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16213        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16214        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16215            if (mLowRamStartTime == 0) {
16216                mLowRamStartTime = now;
16217            }
16218            int step = 0;
16219            int fgTrimLevel;
16220            switch (memFactor) {
16221                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16222                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16223                    break;
16224                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16225                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16226                    break;
16227                default:
16228                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16229                    break;
16230            }
16231            int factor = numTrimming/3;
16232            int minFactor = 2;
16233            if (mHomeProcess != null) minFactor++;
16234            if (mPreviousProcess != null) minFactor++;
16235            if (factor < minFactor) factor = minFactor;
16236            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16237            for (int i=N-1; i>=0; i--) {
16238                ProcessRecord app = mLruProcesses.get(i);
16239                if (allChanged || app.procStateChanged) {
16240                    setProcessTrackerState(app, trackerMemFactor, now);
16241                    app.procStateChanged = false;
16242                }
16243                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16244                        && !app.killedByAm) {
16245                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16246                        try {
16247                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16248                                    "Trimming memory of " + app.processName
16249                                    + " to " + curLevel);
16250                            app.thread.scheduleTrimMemory(curLevel);
16251                        } catch (RemoteException e) {
16252                        }
16253                        if (false) {
16254                            // For now we won't do this; our memory trimming seems
16255                            // to be good enough at this point that destroying
16256                            // activities causes more harm than good.
16257                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16258                                    && app != mHomeProcess && app != mPreviousProcess) {
16259                                // Need to do this on its own message because the stack may not
16260                                // be in a consistent state at this point.
16261                                // For these apps we will also finish their activities
16262                                // to help them free memory.
16263                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16264                            }
16265                        }
16266                    }
16267                    app.trimMemoryLevel = curLevel;
16268                    step++;
16269                    if (step >= factor) {
16270                        step = 0;
16271                        switch (curLevel) {
16272                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16273                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16274                                break;
16275                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16276                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16277                                break;
16278                        }
16279                    }
16280                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16281                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16282                            && app.thread != null) {
16283                        try {
16284                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16285                                    "Trimming memory of heavy-weight " + app.processName
16286                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16287                            app.thread.scheduleTrimMemory(
16288                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16289                        } catch (RemoteException e) {
16290                        }
16291                    }
16292                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16293                } else {
16294                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16295                            || app.systemNoUi) && app.pendingUiClean) {
16296                        // If this application is now in the background and it
16297                        // had done UI, then give it the special trim level to
16298                        // have it free UI resources.
16299                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16300                        if (app.trimMemoryLevel < level && app.thread != null) {
16301                            try {
16302                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16303                                        "Trimming memory of bg-ui " + app.processName
16304                                        + " to " + level);
16305                                app.thread.scheduleTrimMemory(level);
16306                            } catch (RemoteException e) {
16307                            }
16308                        }
16309                        app.pendingUiClean = false;
16310                    }
16311                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16312                        try {
16313                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16314                                    "Trimming memory of fg " + app.processName
16315                                    + " to " + fgTrimLevel);
16316                            app.thread.scheduleTrimMemory(fgTrimLevel);
16317                        } catch (RemoteException e) {
16318                        }
16319                    }
16320                    app.trimMemoryLevel = fgTrimLevel;
16321                }
16322            }
16323        } else {
16324            if (mLowRamStartTime != 0) {
16325                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16326                mLowRamStartTime = 0;
16327            }
16328            for (int i=N-1; i>=0; i--) {
16329                ProcessRecord app = mLruProcesses.get(i);
16330                if (allChanged || app.procStateChanged) {
16331                    setProcessTrackerState(app, trackerMemFactor, now);
16332                    app.procStateChanged = false;
16333                }
16334                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16335                        || app.systemNoUi) && app.pendingUiClean) {
16336                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16337                            && app.thread != null) {
16338                        try {
16339                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16340                                    "Trimming memory of ui hidden " + app.processName
16341                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16342                            app.thread.scheduleTrimMemory(
16343                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16344                        } catch (RemoteException e) {
16345                        }
16346                    }
16347                    app.pendingUiClean = false;
16348                }
16349                app.trimMemoryLevel = 0;
16350            }
16351        }
16352
16353        if (mAlwaysFinishActivities) {
16354            // Need to do this on its own message because the stack may not
16355            // be in a consistent state at this point.
16356            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16357        }
16358
16359        if (allChanged) {
16360            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16361        }
16362
16363        if (mProcessStats.shouldWriteNowLocked(now)) {
16364            mHandler.post(new Runnable() {
16365                @Override public void run() {
16366                    synchronized (ActivityManagerService.this) {
16367                        mProcessStats.writeStateAsyncLocked();
16368                    }
16369                }
16370            });
16371        }
16372
16373        if (DEBUG_OOM_ADJ) {
16374            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16375        }
16376    }
16377
16378    final void trimApplications() {
16379        synchronized (this) {
16380            int i;
16381
16382            // First remove any unused application processes whose package
16383            // has been removed.
16384            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16385                final ProcessRecord app = mRemovedProcesses.get(i);
16386                if (app.activities.size() == 0
16387                        && app.curReceiver == null && app.services.size() == 0) {
16388                    Slog.i(
16389                        TAG, "Exiting empty application process "
16390                        + app.processName + " ("
16391                        + (app.thread != null ? app.thread.asBinder() : null)
16392                        + ")\n");
16393                    if (app.pid > 0 && app.pid != MY_PID) {
16394                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16395                                app.processName, app.setAdj, "empty");
16396                        app.killedByAm = true;
16397                        Process.killProcessQuiet(app.pid);
16398                    } else {
16399                        try {
16400                            app.thread.scheduleExit();
16401                        } catch (Exception e) {
16402                            // Ignore exceptions.
16403                        }
16404                    }
16405                    cleanUpApplicationRecordLocked(app, false, true, -1);
16406                    mRemovedProcesses.remove(i);
16407
16408                    if (app.persistent) {
16409                        if (app.persistent) {
16410                            addAppLocked(app.info, false, null /* ABI override */);
16411                        }
16412                    }
16413                }
16414            }
16415
16416            // Now update the oom adj for all processes.
16417            updateOomAdjLocked();
16418        }
16419    }
16420
16421    /** This method sends the specified signal to each of the persistent apps */
16422    public void signalPersistentProcesses(int sig) throws RemoteException {
16423        if (sig != Process.SIGNAL_USR1) {
16424            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16425        }
16426
16427        synchronized (this) {
16428            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16429                    != PackageManager.PERMISSION_GRANTED) {
16430                throw new SecurityException("Requires permission "
16431                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16432            }
16433
16434            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16435                ProcessRecord r = mLruProcesses.get(i);
16436                if (r.thread != null && r.persistent) {
16437                    Process.sendSignal(r.pid, sig);
16438                }
16439            }
16440        }
16441    }
16442
16443    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16444        if (proc == null || proc == mProfileProc) {
16445            proc = mProfileProc;
16446            path = mProfileFile;
16447            profileType = mProfileType;
16448            clearProfilerLocked();
16449        }
16450        if (proc == null) {
16451            return;
16452        }
16453        try {
16454            proc.thread.profilerControl(false, path, null, profileType);
16455        } catch (RemoteException e) {
16456            throw new IllegalStateException("Process disappeared");
16457        }
16458    }
16459
16460    private void clearProfilerLocked() {
16461        if (mProfileFd != null) {
16462            try {
16463                mProfileFd.close();
16464            } catch (IOException e) {
16465            }
16466        }
16467        mProfileApp = null;
16468        mProfileProc = null;
16469        mProfileFile = null;
16470        mProfileType = 0;
16471        mAutoStopProfiler = false;
16472    }
16473
16474    public boolean profileControl(String process, int userId, boolean start,
16475            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16476
16477        try {
16478            synchronized (this) {
16479                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16480                // its own permission.
16481                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16482                        != PackageManager.PERMISSION_GRANTED) {
16483                    throw new SecurityException("Requires permission "
16484                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16485                }
16486
16487                if (start && fd == null) {
16488                    throw new IllegalArgumentException("null fd");
16489                }
16490
16491                ProcessRecord proc = null;
16492                if (process != null) {
16493                    proc = findProcessLocked(process, userId, "profileControl");
16494                }
16495
16496                if (start && (proc == null || proc.thread == null)) {
16497                    throw new IllegalArgumentException("Unknown process: " + process);
16498                }
16499
16500                if (start) {
16501                    stopProfilerLocked(null, null, 0);
16502                    setProfileApp(proc.info, proc.processName, path, fd, false);
16503                    mProfileProc = proc;
16504                    mProfileType = profileType;
16505                    try {
16506                        fd = fd.dup();
16507                    } catch (IOException e) {
16508                        fd = null;
16509                    }
16510                    proc.thread.profilerControl(start, path, fd, profileType);
16511                    fd = null;
16512                    mProfileFd = null;
16513                } else {
16514                    stopProfilerLocked(proc, path, profileType);
16515                    if (fd != null) {
16516                        try {
16517                            fd.close();
16518                        } catch (IOException e) {
16519                        }
16520                    }
16521                }
16522
16523                return true;
16524            }
16525        } catch (RemoteException e) {
16526            throw new IllegalStateException("Process disappeared");
16527        } finally {
16528            if (fd != null) {
16529                try {
16530                    fd.close();
16531                } catch (IOException e) {
16532                }
16533            }
16534        }
16535    }
16536
16537    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16538        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16539                userId, true, true, callName, null);
16540        ProcessRecord proc = null;
16541        try {
16542            int pid = Integer.parseInt(process);
16543            synchronized (mPidsSelfLocked) {
16544                proc = mPidsSelfLocked.get(pid);
16545            }
16546        } catch (NumberFormatException e) {
16547        }
16548
16549        if (proc == null) {
16550            ArrayMap<String, SparseArray<ProcessRecord>> all
16551                    = mProcessNames.getMap();
16552            SparseArray<ProcessRecord> procs = all.get(process);
16553            if (procs != null && procs.size() > 0) {
16554                proc = procs.valueAt(0);
16555                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16556                    for (int i=1; i<procs.size(); i++) {
16557                        ProcessRecord thisProc = procs.valueAt(i);
16558                        if (thisProc.userId == userId) {
16559                            proc = thisProc;
16560                            break;
16561                        }
16562                    }
16563                }
16564            }
16565        }
16566
16567        return proc;
16568    }
16569
16570    public boolean dumpHeap(String process, int userId, boolean managed,
16571            String path, ParcelFileDescriptor fd) throws RemoteException {
16572
16573        try {
16574            synchronized (this) {
16575                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16576                // its own permission (same as profileControl).
16577                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16578                        != PackageManager.PERMISSION_GRANTED) {
16579                    throw new SecurityException("Requires permission "
16580                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16581                }
16582
16583                if (fd == null) {
16584                    throw new IllegalArgumentException("null fd");
16585                }
16586
16587                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16588                if (proc == null || proc.thread == null) {
16589                    throw new IllegalArgumentException("Unknown process: " + process);
16590                }
16591
16592                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16593                if (!isDebuggable) {
16594                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16595                        throw new SecurityException("Process not debuggable: " + proc);
16596                    }
16597                }
16598
16599                proc.thread.dumpHeap(managed, path, fd);
16600                fd = null;
16601                return true;
16602            }
16603        } catch (RemoteException e) {
16604            throw new IllegalStateException("Process disappeared");
16605        } finally {
16606            if (fd != null) {
16607                try {
16608                    fd.close();
16609                } catch (IOException e) {
16610                }
16611            }
16612        }
16613    }
16614
16615    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16616    public void monitor() {
16617        synchronized (this) { }
16618    }
16619
16620    void onCoreSettingsChange(Bundle settings) {
16621        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16622            ProcessRecord processRecord = mLruProcesses.get(i);
16623            try {
16624                if (processRecord.thread != null) {
16625                    processRecord.thread.setCoreSettings(settings);
16626                }
16627            } catch (RemoteException re) {
16628                /* ignore */
16629            }
16630        }
16631    }
16632
16633    // Multi-user methods
16634
16635    /**
16636     * Start user, if its not already running, but don't bring it to foreground.
16637     */
16638    @Override
16639    public boolean startUserInBackground(final int userId) {
16640        return startUser(userId, /* foreground */ false);
16641    }
16642
16643    /**
16644     * Refreshes the list of users related to the current user when either a
16645     * user switch happens or when a new related user is started in the
16646     * background.
16647     */
16648    private void updateCurrentProfileIdsLocked() {
16649        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16650                mCurrentUserId, false /* enabledOnly */);
16651        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16652        for (int i = 0; i < currentProfileIds.length; i++) {
16653            currentProfileIds[i] = profiles.get(i).id;
16654        }
16655        mCurrentProfileIds = currentProfileIds;
16656    }
16657
16658    private Set getProfileIdsLocked(int userId) {
16659        Set userIds = new HashSet<Integer>();
16660        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16661                userId, false /* enabledOnly */);
16662        for (UserInfo user : profiles) {
16663            userIds.add(Integer.valueOf(user.id));
16664        }
16665        return userIds;
16666    }
16667
16668    @Override
16669    public boolean switchUser(final int userId) {
16670        return startUser(userId, /* foregound */ true);
16671    }
16672
16673    private boolean startUser(final int userId, boolean foreground) {
16674        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16675                != PackageManager.PERMISSION_GRANTED) {
16676            String msg = "Permission Denial: switchUser() from pid="
16677                    + Binder.getCallingPid()
16678                    + ", uid=" + Binder.getCallingUid()
16679                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16680            Slog.w(TAG, msg);
16681            throw new SecurityException(msg);
16682        }
16683
16684        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16685
16686        final long ident = Binder.clearCallingIdentity();
16687        try {
16688            synchronized (this) {
16689                final int oldUserId = mCurrentUserId;
16690                if (oldUserId == userId) {
16691                    return true;
16692                }
16693
16694                mStackSupervisor.setLockTaskModeLocked(null);
16695
16696                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16697                if (userInfo == null) {
16698                    Slog.w(TAG, "No user info for user #" + userId);
16699                    return false;
16700                }
16701
16702                if (foreground) {
16703                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16704                            R.anim.screen_user_enter);
16705                }
16706
16707                boolean needStart = false;
16708
16709                // If the user we are switching to is not currently started, then
16710                // we need to start it now.
16711                if (mStartedUsers.get(userId) == null) {
16712                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16713                    updateStartedUserArrayLocked();
16714                    needStart = true;
16715                }
16716
16717                final Integer userIdInt = Integer.valueOf(userId);
16718                mUserLru.remove(userIdInt);
16719                mUserLru.add(userIdInt);
16720
16721                if (foreground) {
16722                    mCurrentUserId = userId;
16723                    updateCurrentProfileIdsLocked();
16724                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16725                    // Once the internal notion of the active user has switched, we lock the device
16726                    // with the option to show the user switcher on the keyguard.
16727                    mWindowManager.lockNow(null);
16728                } else {
16729                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16730                    updateCurrentProfileIdsLocked();
16731                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16732                    mUserLru.remove(currentUserIdInt);
16733                    mUserLru.add(currentUserIdInt);
16734                }
16735
16736                final UserStartedState uss = mStartedUsers.get(userId);
16737
16738                // Make sure user is in the started state.  If it is currently
16739                // stopping, we need to knock that off.
16740                if (uss.mState == UserStartedState.STATE_STOPPING) {
16741                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16742                    // so we can just fairly silently bring the user back from
16743                    // the almost-dead.
16744                    uss.mState = UserStartedState.STATE_RUNNING;
16745                    updateStartedUserArrayLocked();
16746                    needStart = true;
16747                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16748                    // This means ACTION_SHUTDOWN has been sent, so we will
16749                    // need to treat this as a new boot of the user.
16750                    uss.mState = UserStartedState.STATE_BOOTING;
16751                    updateStartedUserArrayLocked();
16752                    needStart = true;
16753                }
16754
16755                if (uss.mState == UserStartedState.STATE_BOOTING) {
16756                    // Booting up a new user, need to tell system services about it.
16757                    // Note that this is on the same handler as scheduling of broadcasts,
16758                    // which is important because it needs to go first.
16759                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16760                }
16761
16762                if (foreground) {
16763                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16764                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16765                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16766                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16767                            oldUserId, userId, uss));
16768                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16769                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16770                }
16771
16772                if (needStart) {
16773                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16774                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16775                            | Intent.FLAG_RECEIVER_FOREGROUND);
16776                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16777                    broadcastIntentLocked(null, null, intent,
16778                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16779                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16780                }
16781
16782                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16783                    if (userId != UserHandle.USER_OWNER) {
16784                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16785                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16786                        broadcastIntentLocked(null, null, intent, null,
16787                                new IIntentReceiver.Stub() {
16788                                    public void performReceive(Intent intent, int resultCode,
16789                                            String data, Bundle extras, boolean ordered,
16790                                            boolean sticky, int sendingUser) {
16791                                        userInitialized(uss, userId);
16792                                    }
16793                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16794                                true, false, MY_PID, Process.SYSTEM_UID,
16795                                userId);
16796                        uss.initializing = true;
16797                    } else {
16798                        getUserManagerLocked().makeInitialized(userInfo.id);
16799                    }
16800                }
16801
16802                if (foreground) {
16803                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16804                    if (homeInFront) {
16805                        startHomeActivityLocked(userId);
16806                    } else {
16807                        mStackSupervisor.resumeTopActivitiesLocked();
16808                    }
16809                    EventLogTags.writeAmSwitchUser(userId);
16810                    getUserManagerLocked().userForeground(userId);
16811                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16812                } else {
16813                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16814                }
16815
16816                if (needStart) {
16817                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16818                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16819                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16820                    broadcastIntentLocked(null, null, intent,
16821                            null, new IIntentReceiver.Stub() {
16822                                @Override
16823                                public void performReceive(Intent intent, int resultCode, String data,
16824                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16825                                        throws RemoteException {
16826                                }
16827                            }, 0, null, null,
16828                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16829                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16830                }
16831            }
16832        } finally {
16833            Binder.restoreCallingIdentity(ident);
16834        }
16835
16836        return true;
16837    }
16838
16839    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16840        long ident = Binder.clearCallingIdentity();
16841        try {
16842            Intent intent;
16843            if (oldUserId >= 0) {
16844                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16845                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16846                        | Intent.FLAG_RECEIVER_FOREGROUND);
16847                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16848                broadcastIntentLocked(null, null, intent,
16849                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16850                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16851            }
16852            if (newUserId >= 0) {
16853                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16854                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16855                        | Intent.FLAG_RECEIVER_FOREGROUND);
16856                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16857                broadcastIntentLocked(null, null, intent,
16858                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16859                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16860                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16861                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16862                        | Intent.FLAG_RECEIVER_FOREGROUND);
16863                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16864                broadcastIntentLocked(null, null, intent,
16865                        null, null, 0, null, null,
16866                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16867                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16868            }
16869        } finally {
16870            Binder.restoreCallingIdentity(ident);
16871        }
16872    }
16873
16874    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16875            final int newUserId) {
16876        final int N = mUserSwitchObservers.beginBroadcast();
16877        if (N > 0) {
16878            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16879                int mCount = 0;
16880                @Override
16881                public void sendResult(Bundle data) throws RemoteException {
16882                    synchronized (ActivityManagerService.this) {
16883                        if (mCurUserSwitchCallback == this) {
16884                            mCount++;
16885                            if (mCount == N) {
16886                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16887                            }
16888                        }
16889                    }
16890                }
16891            };
16892            synchronized (this) {
16893                uss.switching = true;
16894                mCurUserSwitchCallback = callback;
16895            }
16896            for (int i=0; i<N; i++) {
16897                try {
16898                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16899                            newUserId, callback);
16900                } catch (RemoteException e) {
16901                }
16902            }
16903        } else {
16904            synchronized (this) {
16905                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16906            }
16907        }
16908        mUserSwitchObservers.finishBroadcast();
16909    }
16910
16911    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16912        synchronized (this) {
16913            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16914            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16915        }
16916    }
16917
16918    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16919        mCurUserSwitchCallback = null;
16920        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16921        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16922                oldUserId, newUserId, uss));
16923    }
16924
16925    void userInitialized(UserStartedState uss, int newUserId) {
16926        completeSwitchAndInitalize(uss, newUserId, true, false);
16927    }
16928
16929    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16930        completeSwitchAndInitalize(uss, newUserId, false, true);
16931    }
16932
16933    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16934            boolean clearInitializing, boolean clearSwitching) {
16935        boolean unfrozen = false;
16936        synchronized (this) {
16937            if (clearInitializing) {
16938                uss.initializing = false;
16939                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16940            }
16941            if (clearSwitching) {
16942                uss.switching = false;
16943            }
16944            if (!uss.switching && !uss.initializing) {
16945                mWindowManager.stopFreezingScreen();
16946                unfrozen = true;
16947            }
16948        }
16949        if (unfrozen) {
16950            final int N = mUserSwitchObservers.beginBroadcast();
16951            for (int i=0; i<N; i++) {
16952                try {
16953                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16954                } catch (RemoteException e) {
16955                }
16956            }
16957            mUserSwitchObservers.finishBroadcast();
16958        }
16959    }
16960
16961    void scheduleStartProfilesLocked() {
16962        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16963            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16964                    DateUtils.SECOND_IN_MILLIS);
16965        }
16966    }
16967
16968    void startProfilesLocked() {
16969        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16970        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16971                mCurrentUserId, false /* enabledOnly */);
16972        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16973        for (UserInfo user : profiles) {
16974            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16975                    && user.id != mCurrentUserId) {
16976                toStart.add(user);
16977            }
16978        }
16979        final int n = toStart.size();
16980        int i = 0;
16981        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16982            startUserInBackground(toStart.get(i).id);
16983        }
16984        if (i < n) {
16985            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16986        }
16987    }
16988
16989    void finishUserBoot(UserStartedState uss) {
16990        synchronized (this) {
16991            if (uss.mState == UserStartedState.STATE_BOOTING
16992                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16993                uss.mState = UserStartedState.STATE_RUNNING;
16994                final int userId = uss.mHandle.getIdentifier();
16995                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16996                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16997                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16998                broadcastIntentLocked(null, null, intent,
16999                        null, null, 0, null, null,
17000                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17001                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17002            }
17003        }
17004    }
17005
17006    void finishUserSwitch(UserStartedState uss) {
17007        synchronized (this) {
17008            finishUserBoot(uss);
17009
17010            startProfilesLocked();
17011
17012            int num = mUserLru.size();
17013            int i = 0;
17014            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17015                Integer oldUserId = mUserLru.get(i);
17016                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17017                if (oldUss == null) {
17018                    // Shouldn't happen, but be sane if it does.
17019                    mUserLru.remove(i);
17020                    num--;
17021                    continue;
17022                }
17023                if (oldUss.mState == UserStartedState.STATE_STOPPING
17024                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17025                    // This user is already stopping, doesn't count.
17026                    num--;
17027                    i++;
17028                    continue;
17029                }
17030                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17031                    // Owner and current can't be stopped, but count as running.
17032                    i++;
17033                    continue;
17034                }
17035                // This is a user to be stopped.
17036                stopUserLocked(oldUserId, null);
17037                num--;
17038                i++;
17039            }
17040        }
17041    }
17042
17043    @Override
17044    public int stopUser(final int userId, final IStopUserCallback callback) {
17045        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17046                != PackageManager.PERMISSION_GRANTED) {
17047            String msg = "Permission Denial: switchUser() from pid="
17048                    + Binder.getCallingPid()
17049                    + ", uid=" + Binder.getCallingUid()
17050                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17051            Slog.w(TAG, msg);
17052            throw new SecurityException(msg);
17053        }
17054        if (userId <= 0) {
17055            throw new IllegalArgumentException("Can't stop primary user " + userId);
17056        }
17057        synchronized (this) {
17058            return stopUserLocked(userId, callback);
17059        }
17060    }
17061
17062    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17063        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17064        if (mCurrentUserId == userId) {
17065            return ActivityManager.USER_OP_IS_CURRENT;
17066        }
17067
17068        final UserStartedState uss = mStartedUsers.get(userId);
17069        if (uss == null) {
17070            // User is not started, nothing to do...  but we do need to
17071            // callback if requested.
17072            if (callback != null) {
17073                mHandler.post(new Runnable() {
17074                    @Override
17075                    public void run() {
17076                        try {
17077                            callback.userStopped(userId);
17078                        } catch (RemoteException e) {
17079                        }
17080                    }
17081                });
17082            }
17083            return ActivityManager.USER_OP_SUCCESS;
17084        }
17085
17086        if (callback != null) {
17087            uss.mStopCallbacks.add(callback);
17088        }
17089
17090        if (uss.mState != UserStartedState.STATE_STOPPING
17091                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17092            uss.mState = UserStartedState.STATE_STOPPING;
17093            updateStartedUserArrayLocked();
17094
17095            long ident = Binder.clearCallingIdentity();
17096            try {
17097                // We are going to broadcast ACTION_USER_STOPPING and then
17098                // once that is done send a final ACTION_SHUTDOWN and then
17099                // stop the user.
17100                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17101                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17102                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17103                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17104                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17105                // This is the result receiver for the final shutdown broadcast.
17106                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17107                    @Override
17108                    public void performReceive(Intent intent, int resultCode, String data,
17109                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17110                        finishUserStop(uss);
17111                    }
17112                };
17113                // This is the result receiver for the initial stopping broadcast.
17114                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17115                    @Override
17116                    public void performReceive(Intent intent, int resultCode, String data,
17117                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17118                        // On to the next.
17119                        synchronized (ActivityManagerService.this) {
17120                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17121                                // Whoops, we are being started back up.  Abort, abort!
17122                                return;
17123                            }
17124                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17125                        }
17126                        mSystemServiceManager.stopUser(userId);
17127                        broadcastIntentLocked(null, null, shutdownIntent,
17128                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17129                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17130                    }
17131                };
17132                // Kick things off.
17133                broadcastIntentLocked(null, null, stoppingIntent,
17134                        null, stoppingReceiver, 0, null, null,
17135                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17136                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17137            } finally {
17138                Binder.restoreCallingIdentity(ident);
17139            }
17140        }
17141
17142        return ActivityManager.USER_OP_SUCCESS;
17143    }
17144
17145    void finishUserStop(UserStartedState uss) {
17146        final int userId = uss.mHandle.getIdentifier();
17147        boolean stopped;
17148        ArrayList<IStopUserCallback> callbacks;
17149        synchronized (this) {
17150            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17151            if (mStartedUsers.get(userId) != uss) {
17152                stopped = false;
17153            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17154                stopped = false;
17155            } else {
17156                stopped = true;
17157                // User can no longer run.
17158                mStartedUsers.remove(userId);
17159                mUserLru.remove(Integer.valueOf(userId));
17160                updateStartedUserArrayLocked();
17161
17162                // Clean up all state and processes associated with the user.
17163                // Kill all the processes for the user.
17164                forceStopUserLocked(userId, "finish user");
17165            }
17166        }
17167
17168        for (int i=0; i<callbacks.size(); i++) {
17169            try {
17170                if (stopped) callbacks.get(i).userStopped(userId);
17171                else callbacks.get(i).userStopAborted(userId);
17172            } catch (RemoteException e) {
17173            }
17174        }
17175
17176        if (stopped) {
17177            mSystemServiceManager.cleanupUser(userId);
17178            synchronized (this) {
17179                mStackSupervisor.removeUserLocked(userId);
17180            }
17181        }
17182    }
17183
17184    @Override
17185    public UserInfo getCurrentUser() {
17186        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17187                != PackageManager.PERMISSION_GRANTED) && (
17188                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17189                != PackageManager.PERMISSION_GRANTED)) {
17190            String msg = "Permission Denial: getCurrentUser() from pid="
17191                    + Binder.getCallingPid()
17192                    + ", uid=" + Binder.getCallingUid()
17193                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17194            Slog.w(TAG, msg);
17195            throw new SecurityException(msg);
17196        }
17197        synchronized (this) {
17198            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17199        }
17200    }
17201
17202    int getCurrentUserIdLocked() {
17203        return mCurrentUserId;
17204    }
17205
17206    @Override
17207    public boolean isUserRunning(int userId, boolean orStopped) {
17208        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17209                != PackageManager.PERMISSION_GRANTED) {
17210            String msg = "Permission Denial: isUserRunning() from pid="
17211                    + Binder.getCallingPid()
17212                    + ", uid=" + Binder.getCallingUid()
17213                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17214            Slog.w(TAG, msg);
17215            throw new SecurityException(msg);
17216        }
17217        synchronized (this) {
17218            return isUserRunningLocked(userId, orStopped);
17219        }
17220    }
17221
17222    boolean isUserRunningLocked(int userId, boolean orStopped) {
17223        UserStartedState state = mStartedUsers.get(userId);
17224        if (state == null) {
17225            return false;
17226        }
17227        if (orStopped) {
17228            return true;
17229        }
17230        return state.mState != UserStartedState.STATE_STOPPING
17231                && state.mState != UserStartedState.STATE_SHUTDOWN;
17232    }
17233
17234    @Override
17235    public int[] getRunningUserIds() {
17236        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17237                != PackageManager.PERMISSION_GRANTED) {
17238            String msg = "Permission Denial: isUserRunning() from pid="
17239                    + Binder.getCallingPid()
17240                    + ", uid=" + Binder.getCallingUid()
17241                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17242            Slog.w(TAG, msg);
17243            throw new SecurityException(msg);
17244        }
17245        synchronized (this) {
17246            return mStartedUserArray;
17247        }
17248    }
17249
17250    private void updateStartedUserArrayLocked() {
17251        int num = 0;
17252        for (int i=0; i<mStartedUsers.size();  i++) {
17253            UserStartedState uss = mStartedUsers.valueAt(i);
17254            // This list does not include stopping users.
17255            if (uss.mState != UserStartedState.STATE_STOPPING
17256                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17257                num++;
17258            }
17259        }
17260        mStartedUserArray = new int[num];
17261        num = 0;
17262        for (int i=0; i<mStartedUsers.size();  i++) {
17263            UserStartedState uss = mStartedUsers.valueAt(i);
17264            if (uss.mState != UserStartedState.STATE_STOPPING
17265                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17266                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17267                num++;
17268            }
17269        }
17270    }
17271
17272    @Override
17273    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17274        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17275                != PackageManager.PERMISSION_GRANTED) {
17276            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17277                    + Binder.getCallingPid()
17278                    + ", uid=" + Binder.getCallingUid()
17279                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17280            Slog.w(TAG, msg);
17281            throw new SecurityException(msg);
17282        }
17283
17284        mUserSwitchObservers.register(observer);
17285    }
17286
17287    @Override
17288    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17289        mUserSwitchObservers.unregister(observer);
17290    }
17291
17292    private boolean userExists(int userId) {
17293        if (userId == 0) {
17294            return true;
17295        }
17296        UserManagerService ums = getUserManagerLocked();
17297        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17298    }
17299
17300    int[] getUsersLocked() {
17301        UserManagerService ums = getUserManagerLocked();
17302        return ums != null ? ums.getUserIds() : new int[] { 0 };
17303    }
17304
17305    UserManagerService getUserManagerLocked() {
17306        if (mUserManager == null) {
17307            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17308            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17309        }
17310        return mUserManager;
17311    }
17312
17313    private int applyUserId(int uid, int userId) {
17314        return UserHandle.getUid(userId, uid);
17315    }
17316
17317    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17318        if (info == null) return null;
17319        ApplicationInfo newInfo = new ApplicationInfo(info);
17320        newInfo.uid = applyUserId(info.uid, userId);
17321        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17322                + info.packageName;
17323        return newInfo;
17324    }
17325
17326    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17327        if (aInfo == null
17328                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17329            return aInfo;
17330        }
17331
17332        ActivityInfo info = new ActivityInfo(aInfo);
17333        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17334        return info;
17335    }
17336
17337    private final class LocalService extends ActivityManagerInternal {
17338        @Override
17339        public void goingToSleep() {
17340            ActivityManagerService.this.goingToSleep();
17341        }
17342
17343        @Override
17344        public void wakingUp() {
17345            ActivityManagerService.this.wakingUp();
17346        }
17347    }
17348
17349    /**
17350     * An implementation of IAppTask, that allows an app to manage its own tasks via
17351     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17352     * only the process that calls getAppTasks() can call the AppTask methods.
17353     */
17354    class AppTaskImpl extends IAppTask.Stub {
17355        private int mTaskId;
17356        private int mCallingUid;
17357
17358        public AppTaskImpl(int taskId, int callingUid) {
17359            mTaskId = taskId;
17360            mCallingUid = callingUid;
17361        }
17362
17363        @Override
17364        public void finishAndRemoveTask() {
17365            // Ensure that we are called from the same process that created this AppTask
17366            if (mCallingUid != Binder.getCallingUid()) {
17367                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17368                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17369                return;
17370            }
17371
17372            synchronized (ActivityManagerService.this) {
17373                long origId = Binder.clearCallingIdentity();
17374                try {
17375                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17376                    if (tr != null) {
17377                        // Only kill the process if we are not a new document
17378                        int flags = tr.getBaseIntent().getFlags();
17379                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17380                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17381                        removeTaskByIdLocked(mTaskId,
17382                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17383                    }
17384                } finally {
17385                    Binder.restoreCallingIdentity(origId);
17386                }
17387            }
17388        }
17389
17390        @Override
17391        public ActivityManager.RecentTaskInfo getTaskInfo() {
17392            // Ensure that we are called from the same process that created this AppTask
17393            if (mCallingUid != Binder.getCallingUid()) {
17394                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17395                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17396                return null;
17397            }
17398
17399            synchronized (ActivityManagerService.this) {
17400                long origId = Binder.clearCallingIdentity();
17401                try {
17402                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17403                    if (tr != null) {
17404                        return createRecentTaskInfoFromTaskRecord(tr);
17405                    }
17406                } finally {
17407                    Binder.restoreCallingIdentity(origId);
17408                }
17409                return null;
17410            }
17411        }
17412    }
17413}
17414