1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import android.app.AppOpsManager;
22import android.appwidget.AppWidgetManager;
23import com.android.internal.R;
24import com.android.internal.os.BatteryStatsImpl;
25import com.android.internal.os.ProcessStats;
26import com.android.server.AppOpsService;
27import com.android.server.AttributeCache;
28import com.android.server.IntentResolver;
29import com.android.server.ProcessMap;
30import com.android.server.SystemServer;
31import com.android.server.Watchdog;
32import com.android.server.am.ActivityStack.ActivityState;
33import com.android.server.firewall.IntentFirewall;
34import com.android.server.pm.UserManagerService;
35import com.android.server.wm.AppTransition;
36import com.android.server.wm.WindowManagerService;
37
38import dalvik.system.Zygote;
39
40import android.app.Activity;
41import android.app.ActivityManager;
42import android.app.ActivityManagerNative;
43import android.app.ActivityOptions;
44import android.app.ActivityThread;
45import android.app.AlertDialog;
46import android.app.AppGlobals;
47import android.app.ApplicationErrorReport;
48import android.app.Dialog;
49import android.app.IActivityController;
50import android.app.IApplicationThread;
51import android.app.IInstrumentationWatcher;
52import android.app.INotificationManager;
53import android.app.IProcessObserver;
54import android.app.IServiceConnection;
55import android.app.IStopUserCallback;
56import android.app.IThumbnailReceiver;
57import android.app.IUiAutomationConnection;
58import android.app.IUserSwitchObserver;
59import android.app.Instrumentation;
60import android.app.Notification;
61import android.app.NotificationManager;
62import android.app.PendingIntent;
63import android.app.backup.IBackupManager;
64import android.content.ActivityNotFoundException;
65import android.content.BroadcastReceiver;
66import android.content.ClipData;
67import android.content.ComponentCallbacks2;
68import android.content.ComponentName;
69import android.content.ContentProvider;
70import android.content.ContentResolver;
71import android.content.Context;
72import android.content.DialogInterface;
73import android.content.IContentProvider;
74import android.content.IIntentReceiver;
75import android.content.IIntentSender;
76import android.content.Intent;
77import android.content.IntentFilter;
78import android.content.IntentSender;
79import android.content.pm.ActivityInfo;
80import android.content.pm.ApplicationInfo;
81import android.content.pm.ConfigurationInfo;
82import android.content.pm.IPackageDataObserver;
83import android.content.pm.IPackageManager;
84import android.content.pm.InstrumentationInfo;
85import android.content.pm.PackageInfo;
86import android.content.pm.PackageManager;
87import android.content.pm.UserInfo;
88import android.content.pm.PackageManager.NameNotFoundException;
89import android.content.pm.PathPermission;
90import android.content.pm.ProviderInfo;
91import android.content.pm.ResolveInfo;
92import android.content.pm.ServiceInfo;
93import android.content.res.CompatibilityInfo;
94import android.content.res.Configuration;
95import android.graphics.Bitmap;
96import android.net.Proxy;
97import android.net.ProxyProperties;
98import android.net.Uri;
99import android.os.Binder;
100import android.os.Build;
101import android.os.Bundle;
102import android.os.Debug;
103import android.os.DropBoxManager;
104import android.os.Environment;
105import android.os.FileObserver;
106import android.os.FileUtils;
107import android.os.Handler;
108import android.os.IBinder;
109import android.os.IPermissionController;
110import android.os.IRemoteCallback;
111import android.os.IUserManager;
112import android.os.Looper;
113import android.os.Message;
114import android.os.Parcel;
115import android.os.ParcelFileDescriptor;
116import android.os.Process;
117import android.os.RemoteCallbackList;
118import android.os.RemoteException;
119import android.os.SELinux;
120import android.os.ServiceManager;
121import android.os.StrictMode;
122import android.os.SystemClock;
123import android.os.SystemProperties;
124import android.os.UpdateLock;
125import android.os.UserHandle;
126import android.provider.Settings;
127import android.text.format.Time;
128import android.util.EventLog;
129import android.util.Log;
130import android.util.Pair;
131import android.util.PrintWriterPrinter;
132import android.util.Slog;
133import android.util.SparseArray;
134import android.util.TimeUtils;
135import android.view.Gravity;
136import android.view.LayoutInflater;
137import android.view.View;
138import android.view.WindowManager;
139
140import java.io.BufferedInputStream;
141import java.io.BufferedOutputStream;
142import java.io.BufferedReader;
143import java.io.DataInputStream;
144import java.io.DataOutputStream;
145import java.io.File;
146import java.io.FileDescriptor;
147import java.io.FileInputStream;
148import java.io.FileNotFoundException;
149import java.io.FileOutputStream;
150import java.io.IOException;
151import java.io.InputStreamReader;
152import java.io.PrintWriter;
153import java.io.StringWriter;
154import java.lang.ref.WeakReference;
155import java.util.ArrayList;
156import java.util.Arrays;
157import java.util.Collections;
158import java.util.Comparator;
159import java.util.HashMap;
160import java.util.HashSet;
161import java.util.Iterator;
162import java.util.List;
163import java.util.Locale;
164import java.util.Map;
165import java.util.Set;
166import java.util.concurrent.atomic.AtomicBoolean;
167import java.util.concurrent.atomic.AtomicLong;
168
169public final class ActivityManagerService  extends ActivityManagerNative
170        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
171    private static final String USER_DATA_DIR = "/data/user/";
172    static final String TAG = "ActivityManager";
173    static final String TAG_MU = "ActivityManagerServiceMU";
174    static final boolean DEBUG = false;
175    static final boolean localLOGV = DEBUG;
176    static final boolean DEBUG_SWITCH = localLOGV || false;
177    static final boolean DEBUG_TASKS = localLOGV || false;
178    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
179    static final boolean DEBUG_PAUSE = localLOGV || false;
180    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
181    static final boolean DEBUG_TRANSITION = localLOGV || false;
182    static final boolean DEBUG_BROADCAST = localLOGV || false;
183    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
184    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
185    static final boolean DEBUG_SERVICE = localLOGV || false;
186    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
187    static final boolean DEBUG_VISBILITY = localLOGV || false;
188    static final boolean DEBUG_PROCESSES = localLOGV || false;
189    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
190    static final boolean DEBUG_CLEANUP = localLOGV || false;
191    static final boolean DEBUG_PROVIDER = localLOGV || false;
192    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
193    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
194    static final boolean DEBUG_RESULTS = localLOGV || false;
195    static final boolean DEBUG_BACKUP = localLOGV || false;
196    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
197    static final boolean DEBUG_POWER = localLOGV || false;
198    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
199    static final boolean DEBUG_MU = localLOGV || false;
200    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
201    static final boolean VALIDATE_TOKENS = false;
202    static final boolean SHOW_ACTIVITY_START_TIME = true;
203
204    // Control over CPU and battery monitoring.
205    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
206    static final boolean MONITOR_CPU_USAGE = true;
207    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
208    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
209    static final boolean MONITOR_THREAD_CPU_USAGE = false;
210
211    // The flags that are set for all calls we make to the package manager.
212    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
213
214    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
215
216    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
217
218    // Maximum number of recent tasks that we can remember.
219    static final int MAX_RECENT_TASKS = 20;
220
221    // Amount of time after a call to stopAppSwitches() during which we will
222    // prevent further untrusted switches from happening.
223    static final long APP_SWITCH_DELAY_TIME = 5*1000;
224
225    // How long we wait for a launched process to attach to the activity manager
226    // before we decide it's never going to come up for real.
227    static final int PROC_START_TIMEOUT = 10*1000;
228
229    // How long we wait for a launched process to attach to the activity manager
230    // before we decide it's never going to come up for real, when the process was
231    // started with a wrapper for instrumentation (such as Valgrind) because it
232    // could take much longer than usual.
233    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
234
235    // How long to wait after going idle before forcing apps to GC.
236    static final int GC_TIMEOUT = 5*1000;
237
238    // The minimum amount of time between successive GC requests for a process.
239    static final int GC_MIN_INTERVAL = 60*1000;
240
241    // The rate at which we check for apps using excessive power -- 15 mins.
242    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
243
244    // The minimum sample duration we will allow before deciding we have
245    // enough data on wake locks to start killing things.
246    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
247
248    // The minimum sample duration we will allow before deciding we have
249    // enough data on CPU usage to start killing things.
250    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
251
252    // How long we allow a receiver to run before giving up on it.
253    static final int BROADCAST_FG_TIMEOUT = 10*1000;
254    static final int BROADCAST_BG_TIMEOUT = 60*1000;
255
256    // How long we wait until we timeout on key dispatching.
257    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258
259    // How long we wait until we timeout on key dispatching during instrumentation.
260    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
261
262    // Amount of time we wait for observers to handle a user switch before
263    // giving up on them and unfreezing the screen.
264    static final int USER_SWITCH_TIMEOUT = 2*1000;
265
266    // Maximum number of users we allow to be running at a time.
267    static final int MAX_RUNNING_USERS = 3;
268
269    // How long to wait in getTopActivityExtras for the activity to respond with the result.
270    static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
271
272    static final int MY_PID = Process.myPid();
273
274    static final String[] EMPTY_STRING_ARRAY = new String[0];
275
276    public ActivityStack mMainStack;
277
278    public IntentFirewall mIntentFirewall;
279
280    private final boolean mHeadless;
281
282    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
283    // default actuion automatically.  Important for devices without direct input
284    // devices.
285    private boolean mShowDialogs = true;
286
287    /**
288     * Description of a request to start a new activity, which has been held
289     * due to app switches being disabled.
290     */
291    static class PendingActivityLaunch {
292        ActivityRecord r;
293        ActivityRecord sourceRecord;
294        int startFlags;
295    }
296
297    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
298            = new ArrayList<PendingActivityLaunch>();
299
300
301    BroadcastQueue mFgBroadcastQueue;
302    BroadcastQueue mBgBroadcastQueue;
303    // Convenient for easy iteration over the queues. Foreground is first
304    // so that dispatch of foreground broadcasts gets precedence.
305    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
306
307    BroadcastQueue broadcastQueueForIntent(Intent intent) {
308        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
309        if (DEBUG_BACKGROUND_BROADCAST) {
310            Slog.i(TAG, "Broadcast intent " + intent + " on "
311                    + (isFg ? "foreground" : "background")
312                    + " queue");
313        }
314        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
315    }
316
317    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
318        for (BroadcastQueue queue : mBroadcastQueues) {
319            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
320            if (r != null) {
321                return r;
322            }
323        }
324        return null;
325    }
326
327    /**
328     * Activity we have told the window manager to have key focus.
329     */
330    ActivityRecord mFocusedActivity = null;
331
332    /**
333     * List of intents that were used to start the most recent tasks.
334     */
335    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
336
337    public class PendingActivityExtras extends Binder implements Runnable {
338        public final ActivityRecord activity;
339        public boolean haveResult = false;
340        public Bundle result = null;
341        public PendingActivityExtras(ActivityRecord _activity) {
342            activity = _activity;
343        }
344        @Override
345        public void run() {
346            Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
347            synchronized (this) {
348                haveResult = true;
349                notifyAll();
350            }
351        }
352    }
353
354    final ArrayList<PendingActivityExtras> mPendingActivityExtras
355            = new ArrayList<PendingActivityExtras>();
356
357    /**
358     * Process management.
359     */
360    final ProcessList mProcessList = new ProcessList();
361
362    /**
363     * All of the applications we currently have running organized by name.
364     * The keys are strings of the application package name (as
365     * returned by the package manager), and the keys are ApplicationRecord
366     * objects.
367     */
368    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
369
370    /**
371     * The currently running isolated processes.
372     */
373    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
374
375    /**
376     * Counter for assigning isolated process uids, to avoid frequently reusing the
377     * same ones.
378     */
379    int mNextIsolatedProcessUid = 0;
380
381    /**
382     * The currently running heavy-weight process, if any.
383     */
384    ProcessRecord mHeavyWeightProcess = null;
385
386    /**
387     * The last time that various processes have crashed.
388     */
389    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
390
391    /**
392     * Set of applications that we consider to be bad, and will reject
393     * incoming broadcasts from (which the user has no control over).
394     * Processes are added to this set when they have crashed twice within
395     * a minimum amount of time; they are removed from it when they are
396     * later restarted (hopefully due to some user action).  The value is the
397     * time it was added to the list.
398     */
399    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
400
401    /**
402     * All of the processes we currently have running organized by pid.
403     * The keys are the pid running the application.
404     *
405     * <p>NOTE: This object is protected by its own lock, NOT the global
406     * activity manager lock!
407     */
408    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
409
410    /**
411     * All of the processes that have been forced to be foreground.  The key
412     * is the pid of the caller who requested it (we hold a death
413     * link on it).
414     */
415    abstract class ForegroundToken implements IBinder.DeathRecipient {
416        int pid;
417        IBinder token;
418    }
419    final SparseArray<ForegroundToken> mForegroundProcesses
420            = new SparseArray<ForegroundToken>();
421
422    /**
423     * List of records for processes that someone had tried to start before the
424     * system was ready.  We don't start them at that point, but ensure they
425     * are started by the time booting is complete.
426     */
427    final ArrayList<ProcessRecord> mProcessesOnHold
428            = new ArrayList<ProcessRecord>();
429
430    /**
431     * List of persistent applications that are in the process
432     * of being started.
433     */
434    final ArrayList<ProcessRecord> mPersistentStartingProcesses
435            = new ArrayList<ProcessRecord>();
436
437    /**
438     * Processes that are being forcibly torn down.
439     */
440    final ArrayList<ProcessRecord> mRemovedProcesses
441            = new ArrayList<ProcessRecord>();
442
443    /**
444     * List of running applications, sorted by recent usage.
445     * The first entry in the list is the least recently used.
446     * It contains ApplicationRecord objects.  This list does NOT include
447     * any persistent application records (since we never want to exit them).
448     */
449    final ArrayList<ProcessRecord> mLruProcesses
450            = new ArrayList<ProcessRecord>();
451
452    /**
453     * List of processes that should gc as soon as things are idle.
454     */
455    final ArrayList<ProcessRecord> mProcessesToGc
456            = new ArrayList<ProcessRecord>();
457
458    /**
459     * This is the process holding what we currently consider to be
460     * the "home" activity.
461     */
462    ProcessRecord mHomeProcess;
463
464    /**
465     * This is the process holding the activity the user last visited that
466     * is in a different process from the one they are currently in.
467     */
468    ProcessRecord mPreviousProcess;
469
470    /**
471     * The time at which the previous process was last visible.
472     */
473    long mPreviousProcessVisibleTime;
474
475    /**
476     * Which uses have been started, so are allowed to run code.
477     */
478    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
479
480    /**
481     * LRU list of history of current users.  Most recently current is at the end.
482     */
483    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
484
485    /**
486     * Constant array of the users that are currently started.
487     */
488    int[] mStartedUserArray = new int[] { 0 };
489
490    /**
491     * Registered observers of the user switching mechanics.
492     */
493    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
494            = new RemoteCallbackList<IUserSwitchObserver>();
495
496    /**
497     * Currently active user switch.
498     */
499    Object mCurUserSwitchCallback;
500
501    /**
502     * Packages that the user has asked to have run in screen size
503     * compatibility mode instead of filling the screen.
504     */
505    final CompatModePackages mCompatModePackages;
506
507    /**
508     * Set of PendingResultRecord objects that are currently active.
509     */
510    final HashSet mPendingResultRecords = new HashSet();
511
512    /**
513     * Set of IntentSenderRecord objects that are currently active.
514     */
515    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
516            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
517
518    /**
519     * Fingerprints (hashCode()) of stack traces that we've
520     * already logged DropBox entries for.  Guarded by itself.  If
521     * something (rogue user app) forces this over
522     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
523     */
524    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
525    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
526
527    /**
528     * Strict Mode background batched logging state.
529     *
530     * The string buffer is guarded by itself, and its lock is also
531     * used to determine if another batched write is already
532     * in-flight.
533     */
534    private final StringBuilder mStrictModeBuffer = new StringBuilder();
535
536    /**
537     * Keeps track of all IIntentReceivers that have been registered for
538     * broadcasts.  Hash keys are the receiver IBinder, hash value is
539     * a ReceiverList.
540     */
541    final HashMap mRegisteredReceivers = new HashMap();
542
543    /**
544     * Resolver for broadcast intents to registered receivers.
545     * Holds BroadcastFilter (subclass of IntentFilter).
546     */
547    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
548            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
549        @Override
550        protected boolean allowFilterResult(
551                BroadcastFilter filter, List<BroadcastFilter> dest) {
552            IBinder target = filter.receiverList.receiver.asBinder();
553            for (int i=dest.size()-1; i>=0; i--) {
554                if (dest.get(i).receiverList.receiver.asBinder() == target) {
555                    return false;
556                }
557            }
558            return true;
559        }
560
561        @Override
562        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
563            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
564                    || userId == filter.owningUserId) {
565                return super.newResult(filter, match, userId);
566            }
567            return null;
568        }
569
570        @Override
571        protected BroadcastFilter[] newArray(int size) {
572            return new BroadcastFilter[size];
573        }
574
575        @Override
576        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
577            return packageName.equals(filter.packageName);
578        }
579    };
580
581    /**
582     * State of all active sticky broadcasts per user.  Keys are the action of the
583     * sticky Intent, values are an ArrayList of all broadcasted intents with
584     * that action (which should usually be one).  The SparseArray is keyed
585     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
586     * for stickies that are sent to all users.
587     */
588    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
589            new SparseArray<HashMap<String, ArrayList<Intent>>>();
590
591    final ActiveServices mServices;
592
593    /**
594     * Backup/restore process management
595     */
596    String mBackupAppName = null;
597    BackupRecord mBackupTarget = null;
598
599    /**
600     * List of PendingThumbnailsRecord objects of clients who are still
601     * waiting to receive all of the thumbnails for a task.
602     */
603    final ArrayList mPendingThumbnails = new ArrayList();
604
605    /**
606     * List of HistoryRecord objects that have been finished and must
607     * still report back to a pending thumbnail receiver.
608     */
609    final ArrayList mCancelledThumbnails = new ArrayList();
610
611    final ProviderMap mProviderMap;
612
613    /**
614     * List of content providers who have clients waiting for them.  The
615     * application is currently being launched and the provider will be
616     * removed from this list once it is published.
617     */
618    final ArrayList<ContentProviderRecord> mLaunchingProviders
619            = new ArrayList<ContentProviderRecord>();
620
621    /**
622     * Global set of specific Uri permissions that have been granted.
623     */
624    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
625            = new SparseArray<HashMap<Uri, UriPermission>>();
626
627    CoreSettingsObserver mCoreSettingsObserver;
628
629    /**
630     * Thread-local storage used to carry caller permissions over through
631     * indirect content-provider access.
632     */
633    private class Identity {
634        public int pid;
635        public int uid;
636
637        Identity(int _pid, int _uid) {
638            pid = _pid;
639            uid = _uid;
640        }
641    }
642
643    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
644
645    /**
646     * All information we have collected about the runtime performance of
647     * any user id that can impact battery performance.
648     */
649    final BatteryStatsService mBatteryStatsService;
650
651    /**
652     * Information about component usage
653     */
654    final UsageStatsService mUsageStatsService;
655
656    /**
657     * Information about and control over application operations
658     */
659    final AppOpsService mAppOpsService;
660
661    /**
662     * Current configuration information.  HistoryRecord objects are given
663     * a reference to this object to indicate which configuration they are
664     * currently running in, so this object must be kept immutable.
665     */
666    Configuration mConfiguration = new Configuration();
667
668    /**
669     * Current sequencing integer of the configuration, for skipping old
670     * configurations.
671     */
672    int mConfigurationSeq = 0;
673
674    /**
675     * Hardware-reported OpenGLES version.
676     */
677    final int GL_ES_VERSION;
678
679    /**
680     * List of initialization arguments to pass to all processes when binding applications to them.
681     * For example, references to the commonly used services.
682     */
683    HashMap<String, IBinder> mAppBindArgs;
684
685    /**
686     * Temporary to avoid allocations.  Protected by main lock.
687     */
688    final StringBuilder mStringBuilder = new StringBuilder(256);
689
690    /**
691     * Used to control how we initialize the service.
692     */
693    boolean mStartRunning = false;
694    ComponentName mTopComponent;
695    String mTopAction;
696    String mTopData;
697    boolean mProcessesReady = false;
698    boolean mSystemReady = false;
699    boolean mBooting = false;
700    boolean mWaitingUpdate = false;
701    boolean mDidUpdate = false;
702    boolean mOnBattery = false;
703    boolean mLaunchWarningShown = false;
704
705    Context mContext;
706
707    int mFactoryTest;
708
709    boolean mCheckedForSetup;
710
711    /**
712     * The time at which we will allow normal application switches again,
713     * after a call to {@link #stopAppSwitches()}.
714     */
715    long mAppSwitchesAllowedTime;
716
717    /**
718     * This is set to true after the first switch after mAppSwitchesAllowedTime
719     * is set; any switches after that will clear the time.
720     */
721    boolean mDidAppSwitch;
722
723    /**
724     * Last time (in realtime) at which we checked for power usage.
725     */
726    long mLastPowerCheckRealtime;
727
728    /**
729     * Last time (in uptime) at which we checked for power usage.
730     */
731    long mLastPowerCheckUptime;
732
733    /**
734     * Set while we are wanting to sleep, to prevent any
735     * activities from being started/resumed.
736     */
737    boolean mSleeping = false;
738
739    /**
740     * State of external calls telling us if the device is asleep.
741     */
742    boolean mWentToSleep = false;
743
744    /**
745     * State of external call telling us if the lock screen is shown.
746     */
747    boolean mLockScreenShown = false;
748
749    /**
750     * Set if we are shutting down the system, similar to sleeping.
751     */
752    boolean mShuttingDown = false;
753
754    /**
755     * Task identifier that activities are currently being started
756     * in.  Incremented each time a new task is created.
757     * todo: Replace this with a TokenSpace class that generates non-repeating
758     * integers that won't wrap.
759     */
760    int mCurTask = 1;
761
762    /**
763     * Current sequence id for oom_adj computation traversal.
764     */
765    int mAdjSeq = 0;
766
767    /**
768     * Current sequence id for process LRU updating.
769     */
770    int mLruSeq = 0;
771
772    /**
773     * Keep track of the non-hidden/empty process we last found, to help
774     * determine how to distribute hidden/empty processes next time.
775     */
776    int mNumNonHiddenProcs = 0;
777
778    /**
779     * Keep track of the number of hidden procs, to balance oom adj
780     * distribution between those and empty procs.
781     */
782    int mNumHiddenProcs = 0;
783
784    /**
785     * Keep track of the number of service processes we last found, to
786     * determine on the next iteration which should be B services.
787     */
788    int mNumServiceProcs = 0;
789    int mNewNumServiceProcs = 0;
790
791    /**
792     * System monitoring: number of processes that died since the last
793     * N procs were started.
794     */
795    int[] mProcDeaths = new int[20];
796
797    /**
798     * This is set if we had to do a delayed dexopt of an app before launching
799     * it, to increasing the ANR timeouts in that case.
800     */
801    boolean mDidDexOpt;
802
803    String mDebugApp = null;
804    boolean mWaitForDebugger = false;
805    boolean mDebugTransient = false;
806    String mOrigDebugApp = null;
807    boolean mOrigWaitForDebugger = false;
808    boolean mAlwaysFinishActivities = false;
809    IActivityController mController = null;
810    String mProfileApp = null;
811    ProcessRecord mProfileProc = null;
812    String mProfileFile;
813    ParcelFileDescriptor mProfileFd;
814    int mProfileType = 0;
815    boolean mAutoStopProfiler = false;
816    String mOpenGlTraceApp = null;
817
818    static class ProcessChangeItem {
819        static final int CHANGE_ACTIVITIES = 1<<0;
820        static final int CHANGE_IMPORTANCE= 1<<1;
821        int changes;
822        int uid;
823        int pid;
824        int importance;
825        boolean foregroundActivities;
826    }
827
828    final RemoteCallbackList<IProcessObserver> mProcessObservers
829            = new RemoteCallbackList<IProcessObserver>();
830    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
831
832    final ArrayList<ProcessChangeItem> mPendingProcessChanges
833            = new ArrayList<ProcessChangeItem>();
834    final ArrayList<ProcessChangeItem> mAvailProcessChanges
835            = new ArrayList<ProcessChangeItem>();
836
837    /**
838     * Runtime statistics collection thread.  This object's lock is used to
839     * protect all related state.
840     */
841    final Thread mProcessStatsThread;
842
843    /**
844     * Used to collect process stats when showing not responding dialog.
845     * Protected by mProcessStatsThread.
846     */
847    final ProcessStats mProcessStats = new ProcessStats(
848            MONITOR_THREAD_CPU_USAGE);
849    final AtomicLong mLastCpuTime = new AtomicLong(0);
850    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
851
852    long mLastWriteTime = 0;
853
854    /**
855     * Used to retain an update lock when the foreground activity is in
856     * immersive mode.
857     */
858    final UpdateLock mUpdateLock = new UpdateLock("immersive");
859
860    /**
861     * Set to true after the system has finished booting.
862     */
863    boolean mBooted = false;
864
865    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
866    int mProcessLimitOverride = -1;
867
868    WindowManagerService mWindowManager;
869
870    static ActivityManagerService mSelf;
871    static ActivityThread mSystemThread;
872
873    private int mCurrentUserId = 0;
874    private int[] mCurrentUserArray = new int[] { 0 };
875    private UserManagerService mUserManager;
876
877    private final class AppDeathRecipient implements IBinder.DeathRecipient {
878        final ProcessRecord mApp;
879        final int mPid;
880        final IApplicationThread mAppThread;
881
882        AppDeathRecipient(ProcessRecord app, int pid,
883                IApplicationThread thread) {
884            if (localLOGV) Slog.v(
885                TAG, "New death recipient " + this
886                + " for thread " + thread.asBinder());
887            mApp = app;
888            mPid = pid;
889            mAppThread = thread;
890        }
891
892        public void binderDied() {
893            if (localLOGV) Slog.v(
894                TAG, "Death received in " + this
895                + " for thread " + mAppThread.asBinder());
896            synchronized(ActivityManagerService.this) {
897                appDiedLocked(mApp, mPid, mAppThread);
898            }
899        }
900    }
901
902    static final int SHOW_ERROR_MSG = 1;
903    static final int SHOW_NOT_RESPONDING_MSG = 2;
904    static final int SHOW_FACTORY_ERROR_MSG = 3;
905    static final int UPDATE_CONFIGURATION_MSG = 4;
906    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
907    static final int WAIT_FOR_DEBUGGER_MSG = 6;
908    static final int SERVICE_TIMEOUT_MSG = 12;
909    static final int UPDATE_TIME_ZONE = 13;
910    static final int SHOW_UID_ERROR_MSG = 14;
911    static final int IM_FEELING_LUCKY_MSG = 15;
912    static final int PROC_START_TIMEOUT_MSG = 20;
913    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
914    static final int KILL_APPLICATION_MSG = 22;
915    static final int FINALIZE_PENDING_INTENT_MSG = 23;
916    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
917    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
918    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
919    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
920    static final int CLEAR_DNS_CACHE = 28;
921    static final int UPDATE_HTTP_PROXY = 29;
922    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
923    static final int DISPATCH_PROCESSES_CHANGED = 31;
924    static final int DISPATCH_PROCESS_DIED = 32;
925    static final int REPORT_MEM_USAGE = 33;
926    static final int REPORT_USER_SWITCH_MSG = 34;
927    static final int CONTINUE_USER_SWITCH_MSG = 35;
928    static final int USER_SWITCH_TIMEOUT_MSG = 36;
929    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
930
931    static final int FIRST_ACTIVITY_STACK_MSG = 100;
932    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
933    static final int FIRST_COMPAT_MODE_MSG = 300;
934
935    AlertDialog mUidAlert;
936    CompatModeDialog mCompatModeDialog;
937    long mLastMemUsageReportTime = 0;
938
939    /**
940     * Flag whether the current user is a "monkey", i.e. whether
941     * the UI is driven by a UI automation tool.
942     */
943    private boolean mUserIsMonkey;
944
945    final Handler mHandler = new Handler() {
946        //public Handler() {
947        //    if (localLOGV) Slog.v(TAG, "Handler started!");
948        //}
949
950        public void handleMessage(Message msg) {
951            switch (msg.what) {
952            case SHOW_ERROR_MSG: {
953                HashMap data = (HashMap) msg.obj;
954                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
955                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
956                synchronized (ActivityManagerService.this) {
957                    ProcessRecord proc = (ProcessRecord)data.get("app");
958                    AppErrorResult res = (AppErrorResult) data.get("result");
959                    if (proc != null && proc.crashDialog != null) {
960                        Slog.e(TAG, "App already has crash dialog: " + proc);
961                        if (res != null) {
962                            res.set(0);
963                        }
964                        return;
965                    }
966                    if (!showBackground && UserHandle.getAppId(proc.uid)
967                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
968                            && proc.pid != MY_PID) {
969                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
970                        if (res != null) {
971                            res.set(0);
972                        }
973                        return;
974                    }
975                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
976                        Dialog d = new AppErrorDialog(mContext,
977                                ActivityManagerService.this, res, proc);
978                        d.show();
979                        proc.crashDialog = d;
980                    } else {
981                        // The device is asleep, so just pretend that the user
982                        // saw a crash dialog and hit "force quit".
983                        if (res != null) {
984                            res.set(0);
985                        }
986                    }
987                }
988
989                ensureBootCompleted();
990            } break;
991            case SHOW_NOT_RESPONDING_MSG: {
992                synchronized (ActivityManagerService.this) {
993                    HashMap data = (HashMap) msg.obj;
994                    ProcessRecord proc = (ProcessRecord)data.get("app");
995                    if (proc != null && proc.anrDialog != null) {
996                        Slog.e(TAG, "App already has anr dialog: " + proc);
997                        return;
998                    }
999
1000                    Intent intent = new Intent("android.intent.action.ANR");
1001                    if (!mProcessesReady) {
1002                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1003                                | Intent.FLAG_RECEIVER_FOREGROUND);
1004                    }
1005                    broadcastIntentLocked(null, null, intent,
1006                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1007                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1008
1009                    if (mShowDialogs) {
1010                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1011                                mContext, proc, (ActivityRecord)data.get("activity"),
1012                                msg.arg1 != 0);
1013                        d.show();
1014                        proc.anrDialog = d;
1015                    } else {
1016                        // Just kill the app if there is no dialog to be shown.
1017                        killAppAtUsersRequest(proc, null);
1018                    }
1019                }
1020
1021                ensureBootCompleted();
1022            } break;
1023            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1024                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1025                synchronized (ActivityManagerService.this) {
1026                    ProcessRecord proc = (ProcessRecord) data.get("app");
1027                    if (proc == null) {
1028                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1029                        break;
1030                    }
1031                    if (proc.crashDialog != null) {
1032                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1033                        return;
1034                    }
1035                    AppErrorResult res = (AppErrorResult) data.get("result");
1036                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1037                        Dialog d = new StrictModeViolationDialog(mContext,
1038                                ActivityManagerService.this, res, proc);
1039                        d.show();
1040                        proc.crashDialog = d;
1041                    } else {
1042                        // The device is asleep, so just pretend that the user
1043                        // saw a crash dialog and hit "force quit".
1044                        res.set(0);
1045                    }
1046                }
1047                ensureBootCompleted();
1048            } break;
1049            case SHOW_FACTORY_ERROR_MSG: {
1050                Dialog d = new FactoryErrorDialog(
1051                    mContext, msg.getData().getCharSequence("msg"));
1052                d.show();
1053                ensureBootCompleted();
1054            } break;
1055            case UPDATE_CONFIGURATION_MSG: {
1056                final ContentResolver resolver = mContext.getContentResolver();
1057                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1058            } break;
1059            case GC_BACKGROUND_PROCESSES_MSG: {
1060                synchronized (ActivityManagerService.this) {
1061                    performAppGcsIfAppropriateLocked();
1062                }
1063            } break;
1064            case WAIT_FOR_DEBUGGER_MSG: {
1065                synchronized (ActivityManagerService.this) {
1066                    ProcessRecord app = (ProcessRecord)msg.obj;
1067                    if (msg.arg1 != 0) {
1068                        if (!app.waitedForDebugger) {
1069                            Dialog d = new AppWaitingForDebuggerDialog(
1070                                    ActivityManagerService.this,
1071                                    mContext, app);
1072                            app.waitDialog = d;
1073                            app.waitedForDebugger = true;
1074                            d.show();
1075                        }
1076                    } else {
1077                        if (app.waitDialog != null) {
1078                            app.waitDialog.dismiss();
1079                            app.waitDialog = null;
1080                        }
1081                    }
1082                }
1083            } break;
1084            case SERVICE_TIMEOUT_MSG: {
1085                if (mDidDexOpt) {
1086                    mDidDexOpt = false;
1087                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1088                    nmsg.obj = msg.obj;
1089                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1090                    return;
1091                }
1092                mServices.serviceTimeout((ProcessRecord)msg.obj);
1093            } break;
1094            case UPDATE_TIME_ZONE: {
1095                synchronized (ActivityManagerService.this) {
1096                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1097                        ProcessRecord r = mLruProcesses.get(i);
1098                        if (r.thread != null) {
1099                            try {
1100                                r.thread.updateTimeZone();
1101                            } catch (RemoteException ex) {
1102                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1103                            }
1104                        }
1105                    }
1106                }
1107            } break;
1108            case CLEAR_DNS_CACHE: {
1109                synchronized (ActivityManagerService.this) {
1110                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1111                        ProcessRecord r = mLruProcesses.get(i);
1112                        if (r.thread != null) {
1113                            try {
1114                                r.thread.clearDnsCache();
1115                            } catch (RemoteException ex) {
1116                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1117                            }
1118                        }
1119                    }
1120                }
1121            } break;
1122            case UPDATE_HTTP_PROXY: {
1123                ProxyProperties proxy = (ProxyProperties)msg.obj;
1124                String host = "";
1125                String port = "";
1126                String exclList = "";
1127                if (proxy != null) {
1128                    host = proxy.getHost();
1129                    port = Integer.toString(proxy.getPort());
1130                    exclList = proxy.getExclusionList();
1131                }
1132                synchronized (ActivityManagerService.this) {
1133                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1134                        ProcessRecord r = mLruProcesses.get(i);
1135                        if (r.thread != null) {
1136                            try {
1137                                r.thread.setHttpProxy(host, port, exclList);
1138                            } catch (RemoteException ex) {
1139                                Slog.w(TAG, "Failed to update http proxy for: " +
1140                                        r.info.processName);
1141                            }
1142                        }
1143                    }
1144                }
1145            } break;
1146            case SHOW_UID_ERROR_MSG: {
1147                String title = "System UIDs Inconsistent";
1148                String text = "UIDs on the system are inconsistent, you need to wipe your"
1149                        + " data partition or your device will be unstable.";
1150                Log.e(TAG, title + ": " + text);
1151                if (mShowDialogs) {
1152                    // XXX This is a temporary dialog, no need to localize.
1153                    AlertDialog d = new BaseErrorDialog(mContext);
1154                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1155                    d.setCancelable(false);
1156                    d.setTitle(title);
1157                    d.setMessage(text);
1158                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1159                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1160                    mUidAlert = d;
1161                    d.show();
1162                }
1163            } break;
1164            case IM_FEELING_LUCKY_MSG: {
1165                if (mUidAlert != null) {
1166                    mUidAlert.dismiss();
1167                    mUidAlert = null;
1168                }
1169            } break;
1170            case PROC_START_TIMEOUT_MSG: {
1171                if (mDidDexOpt) {
1172                    mDidDexOpt = false;
1173                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1174                    nmsg.obj = msg.obj;
1175                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1176                    return;
1177                }
1178                ProcessRecord app = (ProcessRecord)msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    processStartTimedOutLocked(app);
1181                }
1182            } break;
1183            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1184                synchronized (ActivityManagerService.this) {
1185                    doPendingActivityLaunchesLocked(true);
1186                }
1187            } break;
1188            case KILL_APPLICATION_MSG: {
1189                synchronized (ActivityManagerService.this) {
1190                    int appid = msg.arg1;
1191                    boolean restart = (msg.arg2 == 1);
1192                    String pkg = (String) msg.obj;
1193                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1194                            UserHandle.USER_ALL);
1195                }
1196            } break;
1197            case FINALIZE_PENDING_INTENT_MSG: {
1198                ((PendingIntentRecord)msg.obj).completeFinalize();
1199            } break;
1200            case POST_HEAVY_NOTIFICATION_MSG: {
1201                INotificationManager inm = NotificationManager.getService();
1202                if (inm == null) {
1203                    return;
1204                }
1205
1206                ActivityRecord root = (ActivityRecord)msg.obj;
1207                ProcessRecord process = root.app;
1208                if (process == null) {
1209                    return;
1210                }
1211
1212                try {
1213                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1214                    String text = mContext.getString(R.string.heavy_weight_notification,
1215                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1216                    Notification notification = new Notification();
1217                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1218                    notification.when = 0;
1219                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1220                    notification.tickerText = text;
1221                    notification.defaults = 0; // please be quiet
1222                    notification.sound = null;
1223                    notification.vibrate = null;
1224                    notification.setLatestEventInfo(context, text,
1225                            mContext.getText(R.string.heavy_weight_notification_detail),
1226                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1227                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1228                                    new UserHandle(root.userId)));
1229
1230                    try {
1231                        int[] outId = new int[1];
1232                        inm.enqueueNotificationWithTag("android", "android", null,
1233                                R.string.heavy_weight_notification,
1234                                notification, outId, root.userId);
1235                    } catch (RuntimeException e) {
1236                        Slog.w(ActivityManagerService.TAG,
1237                                "Error showing notification for heavy-weight app", e);
1238                    } catch (RemoteException e) {
1239                    }
1240                } catch (NameNotFoundException e) {
1241                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1242                }
1243            } break;
1244            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1245                INotificationManager inm = NotificationManager.getService();
1246                if (inm == null) {
1247                    return;
1248                }
1249                try {
1250                    inm.cancelNotificationWithTag("android", null,
1251                            R.string.heavy_weight_notification,  msg.arg1);
1252                } catch (RuntimeException e) {
1253                    Slog.w(ActivityManagerService.TAG,
1254                            "Error canceling notification for service", e);
1255                } catch (RemoteException e) {
1256                }
1257            } break;
1258            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1259                synchronized (ActivityManagerService.this) {
1260                    checkExcessivePowerUsageLocked(true);
1261                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1262                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1263                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1264                }
1265            } break;
1266            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1267                synchronized (ActivityManagerService.this) {
1268                    ActivityRecord ar = (ActivityRecord)msg.obj;
1269                    if (mCompatModeDialog != null) {
1270                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1271                                ar.info.applicationInfo.packageName)) {
1272                            return;
1273                        }
1274                        mCompatModeDialog.dismiss();
1275                        mCompatModeDialog = null;
1276                    }
1277                    if (ar != null && false) {
1278                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1279                                ar.packageName)) {
1280                            int mode = mCompatModePackages.computeCompatModeLocked(
1281                                    ar.info.applicationInfo);
1282                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1283                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1284                                mCompatModeDialog = new CompatModeDialog(
1285                                        ActivityManagerService.this, mContext,
1286                                        ar.info.applicationInfo);
1287                                mCompatModeDialog.show();
1288                            }
1289                        }
1290                    }
1291                }
1292                break;
1293            }
1294            case DISPATCH_PROCESSES_CHANGED: {
1295                dispatchProcessesChanged();
1296                break;
1297            }
1298            case DISPATCH_PROCESS_DIED: {
1299                final int pid = msg.arg1;
1300                final int uid = msg.arg2;
1301                dispatchProcessDied(pid, uid);
1302                break;
1303            }
1304            case REPORT_MEM_USAGE: {
1305                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1306                if (!isDebuggable) {
1307                    return;
1308                }
1309                synchronized (ActivityManagerService.this) {
1310                    long now = SystemClock.uptimeMillis();
1311                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1312                        // Don't report more than every 5 minutes to somewhat
1313                        // avoid spamming.
1314                        return;
1315                    }
1316                    mLastMemUsageReportTime = now;
1317                }
1318                Thread thread = new Thread() {
1319                    @Override public void run() {
1320                        StringBuilder dropBuilder = new StringBuilder(1024);
1321                        StringBuilder logBuilder = new StringBuilder(1024);
1322                        StringWriter oomSw = new StringWriter();
1323                        PrintWriter oomPw = new PrintWriter(oomSw);
1324                        StringWriter catSw = new StringWriter();
1325                        PrintWriter catPw = new PrintWriter(catSw);
1326                        String[] emptyArgs = new String[] { };
1327                        StringBuilder tag = new StringBuilder(128);
1328                        StringBuilder stack = new StringBuilder(128);
1329                        tag.append("Low on memory -- ");
1330                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1331                                tag, stack);
1332                        dropBuilder.append(stack);
1333                        dropBuilder.append('\n');
1334                        dropBuilder.append('\n');
1335                        String oomString = oomSw.toString();
1336                        dropBuilder.append(oomString);
1337                        dropBuilder.append('\n');
1338                        logBuilder.append(oomString);
1339                        try {
1340                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1341                                    "procrank", });
1342                            final InputStreamReader converter = new InputStreamReader(
1343                                    proc.getInputStream());
1344                            BufferedReader in = new BufferedReader(converter);
1345                            String line;
1346                            while (true) {
1347                                line = in.readLine();
1348                                if (line == null) {
1349                                    break;
1350                                }
1351                                if (line.length() > 0) {
1352                                    logBuilder.append(line);
1353                                    logBuilder.append('\n');
1354                                }
1355                                dropBuilder.append(line);
1356                                dropBuilder.append('\n');
1357                            }
1358                            converter.close();
1359                        } catch (IOException e) {
1360                        }
1361                        synchronized (ActivityManagerService.this) {
1362                            catPw.println();
1363                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1364                            catPw.println();
1365                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1366                                    false, false, null);
1367                            catPw.println();
1368                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1369                        }
1370                        dropBuilder.append(catSw.toString());
1371                        addErrorToDropBox("lowmem", null, "system_server", null,
1372                                null, tag.toString(), dropBuilder.toString(), null, null);
1373                        Slog.i(TAG, logBuilder.toString());
1374                        synchronized (ActivityManagerService.this) {
1375                            long now = SystemClock.uptimeMillis();
1376                            if (mLastMemUsageReportTime < now) {
1377                                mLastMemUsageReportTime = now;
1378                            }
1379                        }
1380                    }
1381                };
1382                thread.start();
1383                break;
1384            }
1385            case REPORT_USER_SWITCH_MSG: {
1386                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1387                break;
1388            }
1389            case CONTINUE_USER_SWITCH_MSG: {
1390                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1391                break;
1392            }
1393            case USER_SWITCH_TIMEOUT_MSG: {
1394                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1395                break;
1396            }
1397            case IMMERSIVE_MODE_LOCK_MSG: {
1398                final boolean nextState = (msg.arg1 != 0);
1399                if (mUpdateLock.isHeld() != nextState) {
1400                    if (DEBUG_IMMERSIVE) {
1401                        final ActivityRecord r = (ActivityRecord) msg.obj;
1402                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1403                    }
1404                    if (nextState) {
1405                        mUpdateLock.acquire();
1406                    } else {
1407                        mUpdateLock.release();
1408                    }
1409                }
1410                break;
1411            }
1412            }
1413        }
1414    };
1415
1416    public static void setSystemProcess() {
1417        try {
1418            ActivityManagerService m = mSelf;
1419
1420            ServiceManager.addService("activity", m, true);
1421            ServiceManager.addService("meminfo", new MemBinder(m));
1422            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1423            ServiceManager.addService("dbinfo", new DbBinder(m));
1424            if (MONITOR_CPU_USAGE) {
1425                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1426            }
1427            ServiceManager.addService("permission", new PermissionController(m));
1428
1429            ApplicationInfo info =
1430                mSelf.mContext.getPackageManager().getApplicationInfo(
1431                            "android", STOCK_PM_FLAGS);
1432            mSystemThread.installSystemApplicationInfo(info);
1433
1434            synchronized (mSelf) {
1435                ProcessRecord app = mSelf.newProcessRecordLocked(
1436                        mSystemThread.getApplicationThread(), info,
1437                        info.processName, false);
1438                app.persistent = true;
1439                app.pid = MY_PID;
1440                app.maxAdj = ProcessList.SYSTEM_ADJ;
1441                mSelf.mProcessNames.put(app.processName, app.uid, app);
1442                synchronized (mSelf.mPidsSelfLocked) {
1443                    mSelf.mPidsSelfLocked.put(app.pid, app);
1444                }
1445                mSelf.updateLruProcessLocked(app, true);
1446            }
1447        } catch (PackageManager.NameNotFoundException e) {
1448            throw new RuntimeException(
1449                    "Unable to find android system package", e);
1450        }
1451    }
1452
1453    public void setWindowManager(WindowManagerService wm) {
1454        mWindowManager = wm;
1455    }
1456
1457    public void startObservingNativeCrashes() {
1458        final NativeCrashListener ncl = new NativeCrashListener();
1459        ncl.start();
1460    }
1461
1462    public static final Context main(int factoryTest) {
1463        AThread thr = new AThread();
1464        thr.start();
1465
1466        synchronized (thr) {
1467            while (thr.mService == null) {
1468                try {
1469                    thr.wait();
1470                } catch (InterruptedException e) {
1471                }
1472            }
1473        }
1474
1475        ActivityManagerService m = thr.mService;
1476        mSelf = m;
1477        ActivityThread at = ActivityThread.systemMain();
1478        mSystemThread = at;
1479        Context context = at.getSystemContext();
1480        context.setTheme(android.R.style.Theme_Holo);
1481        m.mContext = context;
1482        m.mFactoryTest = factoryTest;
1483        m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
1484        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
1485
1486        m.mBatteryStatsService.publish(context);
1487        m.mUsageStatsService.publish(context);
1488        m.mAppOpsService.publish(context);
1489
1490        synchronized (thr) {
1491            thr.mReady = true;
1492            thr.notifyAll();
1493        }
1494
1495        m.startRunning(null, null, null, null);
1496
1497        return context;
1498    }
1499
1500    public static ActivityManagerService self() {
1501        return mSelf;
1502    }
1503
1504    static class AThread extends Thread {
1505        ActivityManagerService mService;
1506        Looper mLooper;
1507        boolean mReady = false;
1508
1509        public AThread() {
1510            super("ActivityManager");
1511        }
1512
1513        public void run() {
1514            Looper.prepare();
1515
1516            android.os.Process.setThreadPriority(
1517                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1518            android.os.Process.setCanSelfBackground(false);
1519
1520            ActivityManagerService m = new ActivityManagerService();
1521
1522            synchronized (this) {
1523                mService = m;
1524                mLooper = Looper.myLooper();
1525                notifyAll();
1526            }
1527
1528            synchronized (this) {
1529                while (!mReady) {
1530                    try {
1531                        wait();
1532                    } catch (InterruptedException e) {
1533                    }
1534                }
1535            }
1536
1537            // For debug builds, log event loop stalls to dropbox for analysis.
1538            if (StrictMode.conditionallyEnableDebugLogging()) {
1539                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1540            }
1541
1542            Looper.loop();
1543        }
1544    }
1545
1546    static class MemBinder extends Binder {
1547        ActivityManagerService mActivityManagerService;
1548        MemBinder(ActivityManagerService activityManagerService) {
1549            mActivityManagerService = activityManagerService;
1550        }
1551
1552        @Override
1553        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1554            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1555                    != PackageManager.PERMISSION_GRANTED) {
1556                pw.println("Permission Denial: can't dump meminfo from from pid="
1557                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1558                        + " without permission " + android.Manifest.permission.DUMP);
1559                return;
1560            }
1561
1562            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1563                    false, null, null, null);
1564        }
1565    }
1566
1567    static class GraphicsBinder extends Binder {
1568        ActivityManagerService mActivityManagerService;
1569        GraphicsBinder(ActivityManagerService activityManagerService) {
1570            mActivityManagerService = activityManagerService;
1571        }
1572
1573        @Override
1574        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1575            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1576                    != PackageManager.PERMISSION_GRANTED) {
1577                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1578                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1579                        + " without permission " + android.Manifest.permission.DUMP);
1580                return;
1581            }
1582
1583            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1584        }
1585    }
1586
1587    static class DbBinder extends Binder {
1588        ActivityManagerService mActivityManagerService;
1589        DbBinder(ActivityManagerService activityManagerService) {
1590            mActivityManagerService = activityManagerService;
1591        }
1592
1593        @Override
1594        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1595            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1596                    != PackageManager.PERMISSION_GRANTED) {
1597                pw.println("Permission Denial: can't dump dbinfo from from pid="
1598                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1599                        + " without permission " + android.Manifest.permission.DUMP);
1600                return;
1601            }
1602
1603            mActivityManagerService.dumpDbInfo(fd, pw, args);
1604        }
1605    }
1606
1607    static class CpuBinder extends Binder {
1608        ActivityManagerService mActivityManagerService;
1609        CpuBinder(ActivityManagerService activityManagerService) {
1610            mActivityManagerService = activityManagerService;
1611        }
1612
1613        @Override
1614        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1615            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1616                    != PackageManager.PERMISSION_GRANTED) {
1617                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1618                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1619                        + " without permission " + android.Manifest.permission.DUMP);
1620                return;
1621            }
1622
1623            synchronized (mActivityManagerService.mProcessStatsThread) {
1624                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1625                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1626                        SystemClock.uptimeMillis()));
1627            }
1628        }
1629    }
1630
1631    private ActivityManagerService() {
1632        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1633
1634        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1635        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1636        mBroadcastQueues[0] = mFgBroadcastQueue;
1637        mBroadcastQueues[1] = mBgBroadcastQueue;
1638
1639        mServices = new ActiveServices(this);
1640        mProviderMap = new ProviderMap(this);
1641
1642        File dataDir = Environment.getDataDirectory();
1643        File systemDir = new File(dataDir, "system");
1644        systemDir.mkdirs();
1645        mBatteryStatsService = new BatteryStatsService(new File(
1646                systemDir, "batterystats.bin").toString());
1647        mBatteryStatsService.getActiveStatistics().readLocked();
1648        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1649        mOnBattery = DEBUG_POWER ? true
1650                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1651        mBatteryStatsService.getActiveStatistics().setCallback(this);
1652
1653        mUsageStatsService = new UsageStatsService(new File(
1654                systemDir, "usagestats").toString());
1655        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
1656        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1657
1658        // User 0 is the first and only user that runs at boot.
1659        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1660        mUserLru.add(Integer.valueOf(0));
1661        updateStartedUserArrayLocked();
1662
1663        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1664            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1665
1666        mConfiguration.setToDefaults();
1667        mConfiguration.setLocale(Locale.getDefault());
1668
1669        mConfigurationSeq = mConfiguration.seq = 1;
1670        mProcessStats.init();
1671
1672        mCompatModePackages = new CompatModePackages(this, systemDir);
1673
1674        // Add ourself to the Watchdog monitors.
1675        Watchdog.getInstance().addMonitor(this);
1676
1677        mProcessStatsThread = new Thread("ProcessStats") {
1678            public void run() {
1679                while (true) {
1680                    try {
1681                        try {
1682                            synchronized(this) {
1683                                final long now = SystemClock.uptimeMillis();
1684                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1685                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1686                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1687                                //        + ", write delay=" + nextWriteDelay);
1688                                if (nextWriteDelay < nextCpuDelay) {
1689                                    nextCpuDelay = nextWriteDelay;
1690                                }
1691                                if (nextCpuDelay > 0) {
1692                                    mProcessStatsMutexFree.set(true);
1693                                    this.wait(nextCpuDelay);
1694                                }
1695                            }
1696                        } catch (InterruptedException e) {
1697                        }
1698                        updateCpuStatsNow();
1699                    } catch (Exception e) {
1700                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1701                    }
1702                }
1703            }
1704        };
1705        mProcessStatsThread.start();
1706    }
1707
1708    @Override
1709    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1710            throws RemoteException {
1711        if (code == SYSPROPS_TRANSACTION) {
1712            // We need to tell all apps about the system property change.
1713            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1714            synchronized(this) {
1715                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1716                    final int NA = apps.size();
1717                    for (int ia=0; ia<NA; ia++) {
1718                        ProcessRecord app = apps.valueAt(ia);
1719                        if (app.thread != null) {
1720                            procs.add(app.thread.asBinder());
1721                        }
1722                    }
1723                }
1724            }
1725
1726            int N = procs.size();
1727            for (int i=0; i<N; i++) {
1728                Parcel data2 = Parcel.obtain();
1729                try {
1730                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1731                } catch (RemoteException e) {
1732                }
1733                data2.recycle();
1734            }
1735        }
1736        try {
1737            return super.onTransact(code, data, reply, flags);
1738        } catch (RuntimeException e) {
1739            // The activity manager only throws security exceptions, so let's
1740            // log all others.
1741            if (!(e instanceof SecurityException)) {
1742                Slog.e(TAG, "Activity Manager Crash", e);
1743            }
1744            throw e;
1745        }
1746    }
1747
1748    void updateCpuStats() {
1749        final long now = SystemClock.uptimeMillis();
1750        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1751            return;
1752        }
1753        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1754            synchronized (mProcessStatsThread) {
1755                mProcessStatsThread.notify();
1756            }
1757        }
1758    }
1759
1760    void updateCpuStatsNow() {
1761        synchronized (mProcessStatsThread) {
1762            mProcessStatsMutexFree.set(false);
1763            final long now = SystemClock.uptimeMillis();
1764            boolean haveNewCpuStats = false;
1765
1766            if (MONITOR_CPU_USAGE &&
1767                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1768                mLastCpuTime.set(now);
1769                haveNewCpuStats = true;
1770                mProcessStats.update();
1771                //Slog.i(TAG, mProcessStats.printCurrentState());
1772                //Slog.i(TAG, "Total CPU usage: "
1773                //        + mProcessStats.getTotalCpuPercent() + "%");
1774
1775                // Slog the cpu usage if the property is set.
1776                if ("true".equals(SystemProperties.get("events.cpu"))) {
1777                    int user = mProcessStats.getLastUserTime();
1778                    int system = mProcessStats.getLastSystemTime();
1779                    int iowait = mProcessStats.getLastIoWaitTime();
1780                    int irq = mProcessStats.getLastIrqTime();
1781                    int softIrq = mProcessStats.getLastSoftIrqTime();
1782                    int idle = mProcessStats.getLastIdleTime();
1783
1784                    int total = user + system + iowait + irq + softIrq + idle;
1785                    if (total == 0) total = 1;
1786
1787                    EventLog.writeEvent(EventLogTags.CPU,
1788                            ((user+system+iowait+irq+softIrq) * 100) / total,
1789                            (user * 100) / total,
1790                            (system * 100) / total,
1791                            (iowait * 100) / total,
1792                            (irq * 100) / total,
1793                            (softIrq * 100) / total);
1794                }
1795            }
1796
1797            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1798            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1799            synchronized(bstats) {
1800                synchronized(mPidsSelfLocked) {
1801                    if (haveNewCpuStats) {
1802                        if (mOnBattery) {
1803                            int perc = bstats.startAddingCpuLocked();
1804                            int totalUTime = 0;
1805                            int totalSTime = 0;
1806                            final int N = mProcessStats.countStats();
1807                            for (int i=0; i<N; i++) {
1808                                ProcessStats.Stats st = mProcessStats.getStats(i);
1809                                if (!st.working) {
1810                                    continue;
1811                                }
1812                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1813                                int otherUTime = (st.rel_utime*perc)/100;
1814                                int otherSTime = (st.rel_stime*perc)/100;
1815                                totalUTime += otherUTime;
1816                                totalSTime += otherSTime;
1817                                if (pr != null) {
1818                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1819                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1820                                            st.rel_stime-otherSTime);
1821                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1822                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1823                                } else {
1824                                    BatteryStatsImpl.Uid.Proc ps =
1825                                            bstats.getProcessStatsLocked(st.name, st.pid);
1826                                    if (ps != null) {
1827                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1828                                                st.rel_stime-otherSTime);
1829                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1830                                    }
1831                                }
1832                            }
1833                            bstats.finishAddingCpuLocked(perc, totalUTime,
1834                                    totalSTime, cpuSpeedTimes);
1835                        }
1836                    }
1837                }
1838
1839                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1840                    mLastWriteTime = now;
1841                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1842                }
1843            }
1844        }
1845    }
1846
1847    @Override
1848    public void batteryNeedsCpuUpdate() {
1849        updateCpuStatsNow();
1850    }
1851
1852    @Override
1853    public void batteryPowerChanged(boolean onBattery) {
1854        // When plugging in, update the CPU stats first before changing
1855        // the plug state.
1856        updateCpuStatsNow();
1857        synchronized (this) {
1858            synchronized(mPidsSelfLocked) {
1859                mOnBattery = DEBUG_POWER ? true : onBattery;
1860            }
1861        }
1862    }
1863
1864    /**
1865     * Initialize the application bind args. These are passed to each
1866     * process when the bindApplication() IPC is sent to the process. They're
1867     * lazily setup to make sure the services are running when they're asked for.
1868     */
1869    private HashMap<String, IBinder> getCommonServicesLocked() {
1870        if (mAppBindArgs == null) {
1871            mAppBindArgs = new HashMap<String, IBinder>();
1872
1873            // Setup the application init args
1874            mAppBindArgs.put("package", ServiceManager.getService("package"));
1875            mAppBindArgs.put("window", ServiceManager.getService("window"));
1876            mAppBindArgs.put(Context.ALARM_SERVICE,
1877                    ServiceManager.getService(Context.ALARM_SERVICE));
1878        }
1879        return mAppBindArgs;
1880    }
1881
1882    final void setFocusedActivityLocked(ActivityRecord r) {
1883        if (mFocusedActivity != r) {
1884            mFocusedActivity = r;
1885            if (r != null) {
1886                mWindowManager.setFocusedApp(r.appToken, true);
1887            }
1888            applyUpdateLockStateLocked(r);
1889        }
1890    }
1891
1892    final void applyUpdateLockStateLocked(ActivityRecord r) {
1893        // Modifications to the UpdateLock state are done on our handler, outside
1894        // the activity manager's locks.  The new state is determined based on the
1895        // state *now* of the relevant activity record.  The object is passed to
1896        // the handler solely for logging detail, not to be consulted/modified.
1897        final boolean nextState = r != null && r.immersive;
1898        mHandler.sendMessage(
1899                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
1900    }
1901
1902    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1903        // put it on the LRU to keep track of when it should be exited.
1904        int lrui = mLruProcesses.indexOf(app);
1905        if (lrui >= 0) mLruProcesses.remove(lrui);
1906
1907        int i = mLruProcesses.size()-1;
1908        int skipTop = 0;
1909
1910        app.lruSeq = mLruSeq;
1911
1912        // compute the new weight for this process.
1913        app.lastActivityTime = SystemClock.uptimeMillis();
1914        if (app.activities.size() > 0) {
1915            // If this process has activities, we more strongly want to keep
1916            // it around.
1917            app.lruWeight = app.lastActivityTime;
1918        } else if (app.pubProviders.size() > 0) {
1919            // If this process contains content providers, we want to keep
1920            // it a little more strongly.
1921            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1922            // Also don't let it kick out the first few "real" hidden processes.
1923            skipTop = ProcessList.MIN_HIDDEN_APPS;
1924        } else {
1925            // If this process doesn't have activities, we less strongly
1926            // want to keep it around, and generally want to avoid getting
1927            // in front of any very recently used activities.
1928            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1929            // Also don't let it kick out the first few "real" hidden processes.
1930            skipTop = ProcessList.MIN_HIDDEN_APPS;
1931        }
1932
1933        while (i >= 0) {
1934            ProcessRecord p = mLruProcesses.get(i);
1935            // If this app shouldn't be in front of the first N background
1936            // apps, then skip over that many that are currently hidden.
1937            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1938                skipTop--;
1939            }
1940            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1941                mLruProcesses.add(i+1, app);
1942                break;
1943            }
1944            i--;
1945        }
1946        if (i < 0) {
1947            mLruProcesses.add(0, app);
1948        }
1949
1950        // If the app is currently using a content provider or service,
1951        // bump those processes as well.
1952        if (app.connections.size() > 0) {
1953            for (ConnectionRecord cr : app.connections) {
1954                if (cr.binding != null && cr.binding.service != null
1955                        && cr.binding.service.app != null
1956                        && cr.binding.service.app.lruSeq != mLruSeq) {
1957                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1958                }
1959            }
1960        }
1961        for (int j=app.conProviders.size()-1; j>=0; j--) {
1962            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1963            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1964                updateLruProcessInternalLocked(cpr.proc, i+1);
1965            }
1966        }
1967    }
1968
1969    final void updateLruProcessLocked(ProcessRecord app,
1970            boolean oomAdj) {
1971        mLruSeq++;
1972        updateLruProcessInternalLocked(app, 0);
1973
1974        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1975        if (oomAdj) {
1976            updateOomAdjLocked();
1977        }
1978    }
1979
1980    final ProcessRecord getProcessRecordLocked(
1981            String processName, int uid) {
1982        if (uid == Process.SYSTEM_UID) {
1983            // The system gets to run in any process.  If there are multiple
1984            // processes with the same uid, just pick the first (this
1985            // should never happen).
1986            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1987                    processName);
1988            if (procs == null) return null;
1989            final int N = procs.size();
1990            for (int i = 0; i < N; i++) {
1991                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1992            }
1993        }
1994        ProcessRecord proc = mProcessNames.get(processName, uid);
1995        return proc;
1996    }
1997
1998    void ensurePackageDexOpt(String packageName) {
1999        IPackageManager pm = AppGlobals.getPackageManager();
2000        try {
2001            if (pm.performDexOpt(packageName)) {
2002                mDidDexOpt = true;
2003            }
2004        } catch (RemoteException e) {
2005        }
2006    }
2007
2008    boolean isNextTransitionForward() {
2009        int transit = mWindowManager.getPendingAppTransition();
2010        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2011                || transit == AppTransition.TRANSIT_TASK_OPEN
2012                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2013    }
2014
2015    final ProcessRecord startProcessLocked(String processName,
2016            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2017            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2018            boolean isolated) {
2019        ProcessRecord app;
2020        if (!isolated) {
2021            app = getProcessRecordLocked(processName, info.uid);
2022        } else {
2023            // If this is an isolated process, it can't re-use an existing process.
2024            app = null;
2025        }
2026        // We don't have to do anything more if:
2027        // (1) There is an existing application record; and
2028        // (2) The caller doesn't think it is dead, OR there is no thread
2029        //     object attached to it so we know it couldn't have crashed; and
2030        // (3) There is a pid assigned to it, so it is either starting or
2031        //     already running.
2032        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2033                + " app=" + app + " knownToBeDead=" + knownToBeDead
2034                + " thread=" + (app != null ? app.thread : null)
2035                + " pid=" + (app != null ? app.pid : -1));
2036        if (app != null && app.pid > 0) {
2037            if (!knownToBeDead || app.thread == null) {
2038                // We already have the app running, or are waiting for it to
2039                // come up (we have a pid but not yet its thread), so keep it.
2040                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2041                // If this is a new package in the process, add the package to the list
2042                app.addPackage(info.packageName);
2043                return app;
2044            } else {
2045                // An application record is attached to a previous process,
2046                // clean it up now.
2047                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2048                handleAppDiedLocked(app, true, true);
2049            }
2050        }
2051
2052        String hostingNameStr = hostingName != null
2053                ? hostingName.flattenToShortString() : null;
2054
2055        if (!isolated) {
2056            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2057                // If we are in the background, then check to see if this process
2058                // is bad.  If so, we will just silently fail.
2059                if (mBadProcesses.get(info.processName, info.uid) != null) {
2060                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2061                            + "/" + info.processName);
2062                    return null;
2063                }
2064            } else {
2065                // When the user is explicitly starting a process, then clear its
2066                // crash count so that we won't make it bad until they see at
2067                // least one crash dialog again, and make the process good again
2068                // if it had been bad.
2069                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2070                        + "/" + info.processName);
2071                mProcessCrashTimes.remove(info.processName, info.uid);
2072                if (mBadProcesses.get(info.processName, info.uid) != null) {
2073                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2074                            UserHandle.getUserId(info.uid), info.uid,
2075                            info.processName);
2076                    mBadProcesses.remove(info.processName, info.uid);
2077                    if (app != null) {
2078                        app.bad = false;
2079                    }
2080                }
2081            }
2082        }
2083
2084        if (app == null) {
2085            app = newProcessRecordLocked(null, info, processName, isolated);
2086            if (app == null) {
2087                Slog.w(TAG, "Failed making new process record for "
2088                        + processName + "/" + info.uid + " isolated=" + isolated);
2089                return null;
2090            }
2091            mProcessNames.put(processName, app.uid, app);
2092            if (isolated) {
2093                mIsolatedProcesses.put(app.uid, app);
2094            }
2095        } else {
2096            // If this is a new package in the process, add the package to the list
2097            app.addPackage(info.packageName);
2098        }
2099
2100        // If the system is not ready yet, then hold off on starting this
2101        // process until it is.
2102        if (!mProcessesReady
2103                && !isAllowedWhileBooting(info)
2104                && !allowWhileBooting) {
2105            if (!mProcessesOnHold.contains(app)) {
2106                mProcessesOnHold.add(app);
2107            }
2108            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2109            return app;
2110        }
2111
2112        startProcessLocked(app, hostingType, hostingNameStr);
2113        return (app.pid != 0) ? app : null;
2114    }
2115
2116    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2117        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2118    }
2119
2120    private final void startProcessLocked(ProcessRecord app,
2121            String hostingType, String hostingNameStr) {
2122        if (app.pid > 0 && app.pid != MY_PID) {
2123            synchronized (mPidsSelfLocked) {
2124                mPidsSelfLocked.remove(app.pid);
2125                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2126            }
2127            app.setPid(0);
2128        }
2129
2130        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2131                "startProcessLocked removing on hold: " + app);
2132        mProcessesOnHold.remove(app);
2133
2134        updateCpuStats();
2135
2136        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2137        mProcDeaths[0] = 0;
2138
2139        try {
2140            int uid = app.uid;
2141
2142            int[] gids = null;
2143            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2144            if (!app.isolated) {
2145                int[] permGids = null;
2146                try {
2147                    final PackageManager pm = mContext.getPackageManager();
2148                    permGids = pm.getPackageGids(app.info.packageName);
2149
2150                    if (Environment.isExternalStorageEmulated()) {
2151                        if (pm.checkPermission(
2152                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2153                                app.info.packageName) == PERMISSION_GRANTED) {
2154                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2155                        } else {
2156                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2157                        }
2158                    }
2159                } catch (PackageManager.NameNotFoundException e) {
2160                    Slog.w(TAG, "Unable to retrieve gids", e);
2161                }
2162
2163                /*
2164                 * Add shared application GID so applications can share some
2165                 * resources like shared libraries
2166                 */
2167                if (permGids == null) {
2168                    gids = new int[1];
2169                } else {
2170                    gids = new int[permGids.length + 1];
2171                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2172                }
2173                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2174            }
2175            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2176                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2177                        && mTopComponent != null
2178                        && app.processName.equals(mTopComponent.getPackageName())) {
2179                    uid = 0;
2180                }
2181                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2182                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2183                    uid = 0;
2184                }
2185            }
2186            int debugFlags = 0;
2187            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2188                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2189                // Also turn on CheckJNI for debuggable apps. It's quite
2190                // awkward to turn on otherwise.
2191                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2192            }
2193            // Run the app in safe mode if its manifest requests so or the
2194            // system is booted in safe mode.
2195            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2196                Zygote.systemInSafeMode == true) {
2197                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2198            }
2199            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2200                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2201            }
2202            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2203                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2204            }
2205            if ("1".equals(SystemProperties.get("debug.assert"))) {
2206                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2207            }
2208
2209            // Start the process.  It will either succeed and return a result containing
2210            // the PID of the new process, or else throw a RuntimeException.
2211            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2212                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2213                    app.info.targetSdkVersion, app.info.seinfo, null);
2214
2215            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2216            synchronized (bs) {
2217                if (bs.isOnBattery()) {
2218                    app.batteryStats.incStartsLocked();
2219                }
2220            }
2221
2222            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2223                    UserHandle.getUserId(uid), startResult.pid, uid,
2224                    app.processName, hostingType,
2225                    hostingNameStr != null ? hostingNameStr : "");
2226
2227            if (app.persistent) {
2228                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2229            }
2230
2231            StringBuilder buf = mStringBuilder;
2232            buf.setLength(0);
2233            buf.append("Start proc ");
2234            buf.append(app.processName);
2235            buf.append(" for ");
2236            buf.append(hostingType);
2237            if (hostingNameStr != null) {
2238                buf.append(" ");
2239                buf.append(hostingNameStr);
2240            }
2241            buf.append(": pid=");
2242            buf.append(startResult.pid);
2243            buf.append(" uid=");
2244            buf.append(uid);
2245            buf.append(" gids={");
2246            if (gids != null) {
2247                for (int gi=0; gi<gids.length; gi++) {
2248                    if (gi != 0) buf.append(", ");
2249                    buf.append(gids[gi]);
2250
2251                }
2252            }
2253            buf.append("}");
2254            Slog.i(TAG, buf.toString());
2255            app.setPid(startResult.pid);
2256            app.usingWrapper = startResult.usingWrapper;
2257            app.removed = false;
2258            synchronized (mPidsSelfLocked) {
2259                this.mPidsSelfLocked.put(startResult.pid, app);
2260                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2261                msg.obj = app;
2262                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2263                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2264            }
2265        } catch (RuntimeException e) {
2266            // XXX do better error recovery.
2267            app.setPid(0);
2268            Slog.e(TAG, "Failure starting process " + app.processName, e);
2269        }
2270    }
2271
2272    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2273        if (resumed) {
2274            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2275        } else {
2276            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2277        }
2278    }
2279
2280    boolean startHomeActivityLocked(int userId) {
2281        if (mHeadless) {
2282            // Added because none of the other calls to ensureBootCompleted seem to fire
2283            // when running headless.
2284            ensureBootCompleted();
2285            return false;
2286        }
2287
2288        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2289                && mTopAction == null) {
2290            // We are running in factory test mode, but unable to find
2291            // the factory test app, so just sit around displaying the
2292            // error message and don't try to start anything.
2293            return false;
2294        }
2295        Intent intent = new Intent(
2296            mTopAction,
2297            mTopData != null ? Uri.parse(mTopData) : null);
2298        intent.setComponent(mTopComponent);
2299        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2300            intent.addCategory(Intent.CATEGORY_HOME);
2301        }
2302        ActivityInfo aInfo =
2303            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2304        if (aInfo != null) {
2305            intent.setComponent(new ComponentName(
2306                    aInfo.applicationInfo.packageName, aInfo.name));
2307            // Don't do this if the home app is currently being
2308            // instrumented.
2309            aInfo = new ActivityInfo(aInfo);
2310            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2311            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2312                    aInfo.applicationInfo.uid);
2313            if (app == null || app.instrumentationClass == null) {
2314                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2315                mMainStack.startActivityLocked(null, intent, null, aInfo,
2316                        null, null, 0, 0, 0, null, 0, null, false, null);
2317            }
2318        }
2319
2320        return true;
2321    }
2322
2323    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2324        ActivityInfo ai = null;
2325        ComponentName comp = intent.getComponent();
2326        try {
2327            if (comp != null) {
2328                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2329            } else {
2330                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2331                        intent,
2332                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2333                            flags, userId);
2334
2335                if (info != null) {
2336                    ai = info.activityInfo;
2337                }
2338            }
2339        } catch (RemoteException e) {
2340            // ignore
2341        }
2342
2343        return ai;
2344    }
2345
2346    /**
2347     * Starts the "new version setup screen" if appropriate.
2348     */
2349    void startSetupActivityLocked() {
2350        // Only do this once per boot.
2351        if (mCheckedForSetup) {
2352            return;
2353        }
2354
2355        // We will show this screen if the current one is a different
2356        // version than the last one shown, and we are not running in
2357        // low-level factory test mode.
2358        final ContentResolver resolver = mContext.getContentResolver();
2359        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2360                Settings.Global.getInt(resolver,
2361                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2362            mCheckedForSetup = true;
2363
2364            // See if we should be showing the platform update setup UI.
2365            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2366            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2367                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2368
2369            // We don't allow third party apps to replace this.
2370            ResolveInfo ri = null;
2371            for (int i=0; ris != null && i<ris.size(); i++) {
2372                if ((ris.get(i).activityInfo.applicationInfo.flags
2373                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2374                    ri = ris.get(i);
2375                    break;
2376                }
2377            }
2378
2379            if (ri != null) {
2380                String vers = ri.activityInfo.metaData != null
2381                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2382                        : null;
2383                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2384                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2385                            Intent.METADATA_SETUP_VERSION);
2386                }
2387                String lastVers = Settings.Secure.getString(
2388                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2389                if (vers != null && !vers.equals(lastVers)) {
2390                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2391                    intent.setComponent(new ComponentName(
2392                            ri.activityInfo.packageName, ri.activityInfo.name));
2393                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2394                            null, null, 0, 0, 0, null, 0, null, false, null);
2395                }
2396            }
2397        }
2398    }
2399
2400    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2401        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2402    }
2403
2404    void enforceNotIsolatedCaller(String caller) {
2405        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2406            throw new SecurityException("Isolated process not allowed to call " + caller);
2407        }
2408    }
2409
2410    public int getFrontActivityScreenCompatMode() {
2411        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2412        synchronized (this) {
2413            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2414        }
2415    }
2416
2417    public void setFrontActivityScreenCompatMode(int mode) {
2418        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2419                "setFrontActivityScreenCompatMode");
2420        synchronized (this) {
2421            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2422        }
2423    }
2424
2425    public int getPackageScreenCompatMode(String packageName) {
2426        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2427        synchronized (this) {
2428            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2429        }
2430    }
2431
2432    public void setPackageScreenCompatMode(String packageName, int mode) {
2433        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2434                "setPackageScreenCompatMode");
2435        synchronized (this) {
2436            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2437        }
2438    }
2439
2440    public boolean getPackageAskScreenCompat(String packageName) {
2441        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2442        synchronized (this) {
2443            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2444        }
2445    }
2446
2447    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2448        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2449                "setPackageAskScreenCompat");
2450        synchronized (this) {
2451            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2452        }
2453    }
2454
2455    void reportResumedActivityLocked(ActivityRecord r) {
2456        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2457        updateUsageStats(r, true);
2458    }
2459
2460    private void dispatchProcessesChanged() {
2461        int N;
2462        synchronized (this) {
2463            N = mPendingProcessChanges.size();
2464            if (mActiveProcessChanges.length < N) {
2465                mActiveProcessChanges = new ProcessChangeItem[N];
2466            }
2467            mPendingProcessChanges.toArray(mActiveProcessChanges);
2468            mAvailProcessChanges.addAll(mPendingProcessChanges);
2469            mPendingProcessChanges.clear();
2470            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2471        }
2472        int i = mProcessObservers.beginBroadcast();
2473        while (i > 0) {
2474            i--;
2475            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2476            if (observer != null) {
2477                try {
2478                    for (int j=0; j<N; j++) {
2479                        ProcessChangeItem item = mActiveProcessChanges[j];
2480                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2481                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2482                                    + item.pid + " uid=" + item.uid + ": "
2483                                    + item.foregroundActivities);
2484                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2485                                    item.foregroundActivities);
2486                        }
2487                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2488                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2489                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2490                            observer.onImportanceChanged(item.pid, item.uid,
2491                                    item.importance);
2492                        }
2493                    }
2494                } catch (RemoteException e) {
2495                }
2496            }
2497        }
2498        mProcessObservers.finishBroadcast();
2499    }
2500
2501    private void dispatchProcessDied(int pid, int uid) {
2502        int i = mProcessObservers.beginBroadcast();
2503        while (i > 0) {
2504            i--;
2505            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2506            if (observer != null) {
2507                try {
2508                    observer.onProcessDied(pid, uid);
2509                } catch (RemoteException e) {
2510                }
2511            }
2512        }
2513        mProcessObservers.finishBroadcast();
2514    }
2515
2516    final void doPendingActivityLaunchesLocked(boolean doResume) {
2517        final int N = mPendingActivityLaunches.size();
2518        if (N <= 0) {
2519            return;
2520        }
2521        for (int i=0; i<N; i++) {
2522            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2523            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2524                    pal.startFlags, doResume && i == (N-1), null);
2525        }
2526        mPendingActivityLaunches.clear();
2527    }
2528
2529    public final int startActivity(IApplicationThread caller, String callingPackage,
2530            Intent intent, String resolvedType, IBinder resultTo,
2531            String resultWho, int requestCode, int startFlags,
2532            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2533        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
2534                resultWho, requestCode,
2535                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2536    }
2537
2538    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
2539            Intent intent, String resolvedType, IBinder resultTo,
2540            String resultWho, int requestCode, int startFlags,
2541            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2542        enforceNotIsolatedCaller("startActivity");
2543        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2544                false, true, "startActivity", null);
2545        return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2546                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2547                null, null, options, userId);
2548    }
2549
2550    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
2551            Intent intent, String resolvedType, IBinder resultTo,
2552            String resultWho, int requestCode, int startFlags, String profileFile,
2553            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2554        enforceNotIsolatedCaller("startActivityAndWait");
2555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2556                false, true, "startActivityAndWait", null);
2557        WaitResult res = new WaitResult();
2558        mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2559                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2560                res, null, options, UserHandle.getCallingUserId());
2561        return res;
2562    }
2563
2564    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
2565            Intent intent, String resolvedType, IBinder resultTo,
2566            String resultWho, int requestCode, int startFlags, Configuration config,
2567            Bundle options, int userId) {
2568        enforceNotIsolatedCaller("startActivityWithConfig");
2569        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2570                false, true, "startActivityWithConfig", null);
2571        int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2572                resultTo, resultWho, requestCode, startFlags,
2573                null, null, null, config, options, userId);
2574        return ret;
2575    }
2576
2577    public int startActivityIntentSender(IApplicationThread caller,
2578            IntentSender intent, Intent fillInIntent, String resolvedType,
2579            IBinder resultTo, String resultWho, int requestCode,
2580            int flagsMask, int flagsValues, Bundle options) {
2581        enforceNotIsolatedCaller("startActivityIntentSender");
2582        // Refuse possible leaked file descriptors
2583        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2584            throw new IllegalArgumentException("File descriptors passed in Intent");
2585        }
2586
2587        IIntentSender sender = intent.getTarget();
2588        if (!(sender instanceof PendingIntentRecord)) {
2589            throw new IllegalArgumentException("Bad PendingIntent object");
2590        }
2591
2592        PendingIntentRecord pir = (PendingIntentRecord)sender;
2593
2594        synchronized (this) {
2595            // If this is coming from the currently resumed activity, it is
2596            // effectively saying that app switches are allowed at this point.
2597            if (mMainStack.mResumedActivity != null
2598                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2599                            Binder.getCallingUid()) {
2600                mAppSwitchesAllowedTime = 0;
2601            }
2602        }
2603        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2604                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2605        return ret;
2606    }
2607
2608    public boolean startNextMatchingActivity(IBinder callingActivity,
2609            Intent intent, Bundle options) {
2610        // Refuse possible leaked file descriptors
2611        if (intent != null && intent.hasFileDescriptors() == true) {
2612            throw new IllegalArgumentException("File descriptors passed in Intent");
2613        }
2614
2615        synchronized (this) {
2616            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2617            if (r == null) {
2618                ActivityOptions.abort(options);
2619                return false;
2620            }
2621            if (r.app == null || r.app.thread == null) {
2622                // The caller is not running...  d'oh!
2623                ActivityOptions.abort(options);
2624                return false;
2625            }
2626            intent = new Intent(intent);
2627            // The caller is not allowed to change the data.
2628            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2629            // And we are resetting to find the next component...
2630            intent.setComponent(null);
2631
2632            ActivityInfo aInfo = null;
2633            try {
2634                List<ResolveInfo> resolves =
2635                    AppGlobals.getPackageManager().queryIntentActivities(
2636                            intent, r.resolvedType,
2637                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2638                            UserHandle.getCallingUserId());
2639
2640                // Look for the original activity in the list...
2641                final int N = resolves != null ? resolves.size() : 0;
2642                for (int i=0; i<N; i++) {
2643                    ResolveInfo rInfo = resolves.get(i);
2644                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2645                            && rInfo.activityInfo.name.equals(r.info.name)) {
2646                        // We found the current one...  the next matching is
2647                        // after it.
2648                        i++;
2649                        if (i<N) {
2650                            aInfo = resolves.get(i).activityInfo;
2651                        }
2652                        break;
2653                    }
2654                }
2655            } catch (RemoteException e) {
2656            }
2657
2658            if (aInfo == null) {
2659                // Nobody who is next!
2660                ActivityOptions.abort(options);
2661                return false;
2662            }
2663
2664            intent.setComponent(new ComponentName(
2665                    aInfo.applicationInfo.packageName, aInfo.name));
2666            intent.setFlags(intent.getFlags()&~(
2667                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2668                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2669                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2670                    Intent.FLAG_ACTIVITY_NEW_TASK));
2671
2672            // Okay now we need to start the new activity, replacing the
2673            // currently running activity.  This is a little tricky because
2674            // we want to start the new one as if the current one is finished,
2675            // but not finish the current one first so that there is no flicker.
2676            // And thus...
2677            final boolean wasFinishing = r.finishing;
2678            r.finishing = true;
2679
2680            // Propagate reply information over to the new activity.
2681            final ActivityRecord resultTo = r.resultTo;
2682            final String resultWho = r.resultWho;
2683            final int requestCode = r.requestCode;
2684            r.resultTo = null;
2685            if (resultTo != null) {
2686                resultTo.removeResultsLocked(r, resultWho, requestCode);
2687            }
2688
2689            final long origId = Binder.clearCallingIdentity();
2690            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2691                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2692                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
2693                    options, false, null);
2694            Binder.restoreCallingIdentity(origId);
2695
2696            r.finishing = wasFinishing;
2697            if (res != ActivityManager.START_SUCCESS) {
2698                return false;
2699            }
2700            return true;
2701        }
2702    }
2703
2704    final int startActivityInPackage(int uid, String callingPackage,
2705            Intent intent, String resolvedType, IBinder resultTo,
2706            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2707
2708        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2709                false, true, "startActivityInPackage", null);
2710
2711        int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
2712                resultTo, resultWho, requestCode, startFlags,
2713                null, null, null, null, options, userId);
2714        return ret;
2715    }
2716
2717    public final int startActivities(IApplicationThread caller, String callingPackage,
2718            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2719            int userId) {
2720        enforceNotIsolatedCaller("startActivities");
2721        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2722                false, true, "startActivity", null);
2723        int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
2724                resolvedTypes, resultTo, options, userId);
2725        return ret;
2726    }
2727
2728    final int startActivitiesInPackage(int uid, String callingPackage,
2729            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2730            Bundle options, int userId) {
2731
2732        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2733                false, true, "startActivityInPackage", null);
2734        int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
2735                resultTo, options, userId);
2736        return ret;
2737    }
2738
2739    final void addRecentTaskLocked(TaskRecord task) {
2740        int N = mRecentTasks.size();
2741        // Quick case: check if the top-most recent task is the same.
2742        if (N > 0 && mRecentTasks.get(0) == task) {
2743            return;
2744        }
2745        // Remove any existing entries that are the same kind of task.
2746        for (int i=0; i<N; i++) {
2747            TaskRecord tr = mRecentTasks.get(i);
2748            if (task.userId == tr.userId
2749                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2750                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2751                mRecentTasks.remove(i);
2752                i--;
2753                N--;
2754                if (task.intent == null) {
2755                    // If the new recent task we are adding is not fully
2756                    // specified, then replace it with the existing recent task.
2757                    task = tr;
2758                }
2759            }
2760        }
2761        if (N >= MAX_RECENT_TASKS) {
2762            mRecentTasks.remove(N-1);
2763        }
2764        mRecentTasks.add(0, task);
2765    }
2766
2767    public void setRequestedOrientation(IBinder token,
2768            int requestedOrientation) {
2769        synchronized (this) {
2770            ActivityRecord r = mMainStack.isInStackLocked(token);
2771            if (r == null) {
2772                return;
2773            }
2774            final long origId = Binder.clearCallingIdentity();
2775            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2776            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2777                    mConfiguration,
2778                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2779            if (config != null) {
2780                r.frozenBeforeDestroy = true;
2781                if (!updateConfigurationLocked(config, r, false, false)) {
2782                    mMainStack.resumeTopActivityLocked(null);
2783                }
2784            }
2785            Binder.restoreCallingIdentity(origId);
2786        }
2787    }
2788
2789    public int getRequestedOrientation(IBinder token) {
2790        synchronized (this) {
2791            ActivityRecord r = mMainStack.isInStackLocked(token);
2792            if (r == null) {
2793                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2794            }
2795            return mWindowManager.getAppOrientation(r.appToken);
2796        }
2797    }
2798
2799    /**
2800     * This is the internal entry point for handling Activity.finish().
2801     *
2802     * @param token The Binder token referencing the Activity we want to finish.
2803     * @param resultCode Result code, if any, from this Activity.
2804     * @param resultData Result data (Intent), if any, from this Activity.
2805     *
2806     * @return Returns true if the activity successfully finished, or false if it is still running.
2807     */
2808    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2809        // Refuse possible leaked file descriptors
2810        if (resultData != null && resultData.hasFileDescriptors() == true) {
2811            throw new IllegalArgumentException("File descriptors passed in Intent");
2812        }
2813
2814        synchronized(this) {
2815            if (mController != null) {
2816                // Find the first activity that is not finishing.
2817                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2818                if (next != null) {
2819                    // ask watcher if this is allowed
2820                    boolean resumeOK = true;
2821                    try {
2822                        resumeOK = mController.activityResuming(next.packageName);
2823                    } catch (RemoteException e) {
2824                        mController = null;
2825                        Watchdog.getInstance().setActivityController(null);
2826                    }
2827
2828                    if (!resumeOK) {
2829                        return false;
2830                    }
2831                }
2832            }
2833            final long origId = Binder.clearCallingIdentity();
2834            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2835                    resultData, "app-request", true);
2836            Binder.restoreCallingIdentity(origId);
2837            return res;
2838        }
2839    }
2840
2841    public final void finishHeavyWeightApp() {
2842        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2843                != PackageManager.PERMISSION_GRANTED) {
2844            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2845                    + Binder.getCallingPid()
2846                    + ", uid=" + Binder.getCallingUid()
2847                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2848            Slog.w(TAG, msg);
2849            throw new SecurityException(msg);
2850        }
2851
2852        synchronized(this) {
2853            if (mHeavyWeightProcess == null) {
2854                return;
2855            }
2856
2857            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2858                    mHeavyWeightProcess.activities);
2859            for (int i=0; i<activities.size(); i++) {
2860                ActivityRecord r = activities.get(i);
2861                if (!r.finishing) {
2862                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2863                    if (index >= 0) {
2864                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2865                                null, "finish-heavy", true);
2866                    }
2867                }
2868            }
2869
2870            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2871                    mHeavyWeightProcess.userId, 0));
2872            mHeavyWeightProcess = null;
2873        }
2874    }
2875
2876    public void crashApplication(int uid, int initialPid, String packageName,
2877            String message) {
2878        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2879                != PackageManager.PERMISSION_GRANTED) {
2880            String msg = "Permission Denial: crashApplication() from pid="
2881                    + Binder.getCallingPid()
2882                    + ", uid=" + Binder.getCallingUid()
2883                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2884            Slog.w(TAG, msg);
2885            throw new SecurityException(msg);
2886        }
2887
2888        synchronized(this) {
2889            ProcessRecord proc = null;
2890
2891            // Figure out which process to kill.  We don't trust that initialPid
2892            // still has any relation to current pids, so must scan through the
2893            // list.
2894            synchronized (mPidsSelfLocked) {
2895                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2896                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2897                    if (p.uid != uid) {
2898                        continue;
2899                    }
2900                    if (p.pid == initialPid) {
2901                        proc = p;
2902                        break;
2903                    }
2904                    for (String str : p.pkgList) {
2905                        if (str.equals(packageName)) {
2906                            proc = p;
2907                        }
2908                    }
2909                }
2910            }
2911
2912            if (proc == null) {
2913                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2914                        + " initialPid=" + initialPid
2915                        + " packageName=" + packageName);
2916                return;
2917            }
2918
2919            if (proc.thread != null) {
2920                if (proc.pid == Process.myPid()) {
2921                    Log.w(TAG, "crashApplication: trying to crash self!");
2922                    return;
2923                }
2924                long ident = Binder.clearCallingIdentity();
2925                try {
2926                    proc.thread.scheduleCrash(message);
2927                } catch (RemoteException e) {
2928                }
2929                Binder.restoreCallingIdentity(ident);
2930            }
2931        }
2932    }
2933
2934    public final void finishSubActivity(IBinder token, String resultWho,
2935            int requestCode) {
2936        synchronized(this) {
2937            final long origId = Binder.clearCallingIdentity();
2938            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2939            Binder.restoreCallingIdentity(origId);
2940        }
2941    }
2942
2943    public boolean finishActivityAffinity(IBinder token) {
2944        synchronized(this) {
2945            final long origId = Binder.clearCallingIdentity();
2946            boolean res = mMainStack.finishActivityAffinityLocked(token);
2947            Binder.restoreCallingIdentity(origId);
2948            return res;
2949        }
2950    }
2951
2952    public boolean willActivityBeVisible(IBinder token) {
2953        synchronized(this) {
2954            int i;
2955            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2956                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2957                if (r.appToken == token) {
2958                    return true;
2959                }
2960                if (r.fullscreen && !r.finishing) {
2961                    return false;
2962                }
2963            }
2964            return true;
2965        }
2966    }
2967
2968    public void overridePendingTransition(IBinder token, String packageName,
2969            int enterAnim, int exitAnim) {
2970        synchronized(this) {
2971            ActivityRecord self = mMainStack.isInStackLocked(token);
2972            if (self == null) {
2973                return;
2974            }
2975
2976            final long origId = Binder.clearCallingIdentity();
2977
2978            if (self.state == ActivityState.RESUMED
2979                    || self.state == ActivityState.PAUSING) {
2980                mWindowManager.overridePendingAppTransition(packageName,
2981                        enterAnim, exitAnim, null);
2982            }
2983
2984            Binder.restoreCallingIdentity(origId);
2985        }
2986    }
2987
2988    /**
2989     * Main function for removing an existing process from the activity manager
2990     * as a result of that process going away.  Clears out all connections
2991     * to the process.
2992     */
2993    private final void handleAppDiedLocked(ProcessRecord app,
2994            boolean restarting, boolean allowRestart) {
2995        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2996        if (!restarting) {
2997            mLruProcesses.remove(app);
2998        }
2999
3000        if (mProfileProc == app) {
3001            clearProfilerLocked();
3002        }
3003
3004        // Just in case...
3005        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
3006            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
3007                    "App died while pausing: " + mMainStack.mPausingActivity);
3008            mMainStack.mPausingActivity = null;
3009        }
3010        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
3011            mMainStack.mLastPausedActivity = null;
3012        }
3013
3014        // Remove this application's activities from active lists.
3015        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
3016
3017        app.activities.clear();
3018
3019        if (app.instrumentationClass != null) {
3020            Slog.w(TAG, "Crash of app " + app.processName
3021                  + " running instrumentation " + app.instrumentationClass);
3022            Bundle info = new Bundle();
3023            info.putString("shortMsg", "Process crashed.");
3024            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3025        }
3026
3027        if (!restarting) {
3028            if (!mMainStack.resumeTopActivityLocked(null)) {
3029                // If there was nothing to resume, and we are not already
3030                // restarting this process, but there is a visible activity that
3031                // is hosted by the process...  then make sure all visible
3032                // activities are running, taking care of restarting this
3033                // process.
3034                if (hasVisibleActivities) {
3035                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
3036                }
3037            }
3038        }
3039    }
3040
3041    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3042        IBinder threadBinder = thread.asBinder();
3043        // Find the application record.
3044        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3045            ProcessRecord rec = mLruProcesses.get(i);
3046            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3047                return i;
3048            }
3049        }
3050        return -1;
3051    }
3052
3053    final ProcessRecord getRecordForAppLocked(
3054            IApplicationThread thread) {
3055        if (thread == null) {
3056            return null;
3057        }
3058
3059        int appIndex = getLRURecordIndexForAppLocked(thread);
3060        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3061    }
3062
3063    final void appDiedLocked(ProcessRecord app, int pid,
3064            IApplicationThread thread) {
3065
3066        mProcDeaths[0]++;
3067
3068        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3069        synchronized (stats) {
3070            stats.noteProcessDiedLocked(app.info.uid, pid);
3071        }
3072
3073        // Clean up already done if the process has been re-started.
3074        if (app.pid == pid && app.thread != null &&
3075                app.thread.asBinder() == thread.asBinder()) {
3076            if (!app.killedBackground) {
3077                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3078                        + ") has died.");
3079            }
3080            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3081            if (DEBUG_CLEANUP) Slog.v(
3082                TAG, "Dying app: " + app + ", pid: " + pid
3083                + ", thread: " + thread.asBinder());
3084            boolean doLowMem = app.instrumentationClass == null;
3085            handleAppDiedLocked(app, false, true);
3086
3087            if (doLowMem) {
3088                // If there are no longer any background processes running,
3089                // and the app that died was not running instrumentation,
3090                // then tell everyone we are now low on memory.
3091                boolean haveBg = false;
3092                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3093                    ProcessRecord rec = mLruProcesses.get(i);
3094                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3095                        haveBg = true;
3096                        break;
3097                    }
3098                }
3099
3100                if (!haveBg) {
3101                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3102                    long now = SystemClock.uptimeMillis();
3103                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3104                        ProcessRecord rec = mLruProcesses.get(i);
3105                        if (rec != app && rec.thread != null &&
3106                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3107                            // The low memory report is overriding any current
3108                            // state for a GC request.  Make sure to do
3109                            // heavy/important/visible/foreground processes first.
3110                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3111                                rec.lastRequestedGc = 0;
3112                            } else {
3113                                rec.lastRequestedGc = rec.lastLowMemory;
3114                            }
3115                            rec.reportLowMemory = true;
3116                            rec.lastLowMemory = now;
3117                            mProcessesToGc.remove(rec);
3118                            addProcessToGcListLocked(rec);
3119                        }
3120                    }
3121                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3122                    scheduleAppGcsLocked();
3123                }
3124            }
3125        } else if (app.pid != pid) {
3126            // A new process has already been started.
3127            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3128                    + ") has died and restarted (pid " + app.pid + ").");
3129            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3130        } else if (DEBUG_PROCESSES) {
3131            Slog.d(TAG, "Received spurious death notification for thread "
3132                    + thread.asBinder());
3133        }
3134    }
3135
3136    /**
3137     * If a stack trace dump file is configured, dump process stack traces.
3138     * @param clearTraces causes the dump file to be erased prior to the new
3139     *    traces being written, if true; when false, the new traces will be
3140     *    appended to any existing file content.
3141     * @param firstPids of dalvik VM processes to dump stack traces for first
3142     * @param lastPids of dalvik VM processes to dump stack traces for last
3143     * @param nativeProcs optional list of native process names to dump stack crawls
3144     * @return file containing stack traces, or null if no dump file is configured
3145     */
3146    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3147            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3148        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3149        if (tracesPath == null || tracesPath.length() == 0) {
3150            return null;
3151        }
3152
3153        File tracesFile = new File(tracesPath);
3154        try {
3155            File tracesDir = tracesFile.getParentFile();
3156            if (!tracesDir.exists()) {
3157                tracesFile.mkdirs();
3158                if (!SELinux.restorecon(tracesDir)) {
3159                    return null;
3160                }
3161            }
3162            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3163
3164            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3165            tracesFile.createNewFile();
3166            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3167        } catch (IOException e) {
3168            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3169            return null;
3170        }
3171
3172        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3173        return tracesFile;
3174    }
3175
3176    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3177            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3178        // Use a FileObserver to detect when traces finish writing.
3179        // The order of traces is considered important to maintain for legibility.
3180        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3181            public synchronized void onEvent(int event, String path) { notify(); }
3182        };
3183
3184        try {
3185            observer.startWatching();
3186
3187            // First collect all of the stacks of the most important pids.
3188            if (firstPids != null) {
3189                try {
3190                    int num = firstPids.size();
3191                    for (int i = 0; i < num; i++) {
3192                        synchronized (observer) {
3193                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3194                            observer.wait(200);  // Wait for write-close, give up after 200msec
3195                        }
3196                    }
3197                } catch (InterruptedException e) {
3198                    Log.wtf(TAG, e);
3199                }
3200            }
3201
3202            // Next measure CPU usage.
3203            if (processStats != null) {
3204                processStats.init();
3205                System.gc();
3206                processStats.update();
3207                try {
3208                    synchronized (processStats) {
3209                        processStats.wait(500); // measure over 1/2 second.
3210                    }
3211                } catch (InterruptedException e) {
3212                }
3213                processStats.update();
3214
3215                // We'll take the stack crawls of just the top apps using CPU.
3216                final int N = processStats.countWorkingStats();
3217                int numProcs = 0;
3218                for (int i=0; i<N && numProcs<5; i++) {
3219                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3220                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3221                        numProcs++;
3222                        try {
3223                            synchronized (observer) {
3224                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3225                                observer.wait(200);  // Wait for write-close, give up after 200msec
3226                            }
3227                        } catch (InterruptedException e) {
3228                            Log.wtf(TAG, e);
3229                        }
3230
3231                    }
3232                }
3233            }
3234
3235        } finally {
3236            observer.stopWatching();
3237        }
3238
3239        if (nativeProcs != null) {
3240            int[] pids = Process.getPidsForCommands(nativeProcs);
3241            if (pids != null) {
3242                for (int pid : pids) {
3243                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3244                }
3245            }
3246        }
3247    }
3248
3249    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3250        if (true || IS_USER_BUILD) {
3251            return;
3252        }
3253        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3254        if (tracesPath == null || tracesPath.length() == 0) {
3255            return;
3256        }
3257
3258        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3259        StrictMode.allowThreadDiskWrites();
3260        try {
3261            final File tracesFile = new File(tracesPath);
3262            final File tracesDir = tracesFile.getParentFile();
3263            final File tracesTmp = new File(tracesDir, "__tmp__");
3264            try {
3265                if (!tracesDir.exists()) {
3266                    tracesFile.mkdirs();
3267                    if (!SELinux.restorecon(tracesDir.getPath())) {
3268                        return;
3269                    }
3270                }
3271                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3272
3273                if (tracesFile.exists()) {
3274                    tracesTmp.delete();
3275                    tracesFile.renameTo(tracesTmp);
3276                }
3277                StringBuilder sb = new StringBuilder();
3278                Time tobj = new Time();
3279                tobj.set(System.currentTimeMillis());
3280                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3281                sb.append(": ");
3282                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3283                sb.append(" since ");
3284                sb.append(msg);
3285                FileOutputStream fos = new FileOutputStream(tracesFile);
3286                fos.write(sb.toString().getBytes());
3287                if (app == null) {
3288                    fos.write("\n*** No application process!".getBytes());
3289                }
3290                fos.close();
3291                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3292            } catch (IOException e) {
3293                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3294                return;
3295            }
3296
3297            if (app != null) {
3298                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3299                firstPids.add(app.pid);
3300                dumpStackTraces(tracesPath, firstPids, null, null, null);
3301            }
3302
3303            File lastTracesFile = null;
3304            File curTracesFile = null;
3305            for (int i=9; i>=0; i--) {
3306                String name = String.format("slow%02d.txt", i);
3307                curTracesFile = new File(tracesDir, name);
3308                if (curTracesFile.exists()) {
3309                    if (lastTracesFile != null) {
3310                        curTracesFile.renameTo(lastTracesFile);
3311                    } else {
3312                        curTracesFile.delete();
3313                    }
3314                }
3315                lastTracesFile = curTracesFile;
3316            }
3317            tracesFile.renameTo(curTracesFile);
3318            if (tracesTmp.exists()) {
3319                tracesTmp.renameTo(tracesFile);
3320            }
3321        } finally {
3322            StrictMode.setThreadPolicy(oldPolicy);
3323        }
3324    }
3325
3326    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3327            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3328        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3329        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3330
3331        if (mController != null) {
3332            try {
3333                // 0 == continue, -1 = kill process immediately
3334                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3335                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3336            } catch (RemoteException e) {
3337                mController = null;
3338                Watchdog.getInstance().setActivityController(null);
3339            }
3340        }
3341
3342        long anrTime = SystemClock.uptimeMillis();
3343        if (MONITOR_CPU_USAGE) {
3344            updateCpuStatsNow();
3345        }
3346
3347        synchronized (this) {
3348            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3349            if (mShuttingDown) {
3350                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3351                return;
3352            } else if (app.notResponding) {
3353                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3354                return;
3355            } else if (app.crashing) {
3356                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3357                return;
3358            }
3359
3360            // In case we come through here for the same app before completing
3361            // this one, mark as anring now so we will bail out.
3362            app.notResponding = true;
3363
3364            // Log the ANR to the event log.
3365            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3366                    app.processName, app.info.flags, annotation);
3367
3368            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3369            firstPids.add(app.pid);
3370
3371            int parentPid = app.pid;
3372            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3373            if (parentPid != app.pid) firstPids.add(parentPid);
3374
3375            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3376
3377            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3378                ProcessRecord r = mLruProcesses.get(i);
3379                if (r != null && r.thread != null) {
3380                    int pid = r.pid;
3381                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3382                        if (r.persistent) {
3383                            firstPids.add(pid);
3384                        } else {
3385                            lastPids.put(pid, Boolean.TRUE);
3386                        }
3387                    }
3388                }
3389            }
3390        }
3391
3392        // Log the ANR to the main log.
3393        StringBuilder info = new StringBuilder();
3394        info.setLength(0);
3395        info.append("ANR in ").append(app.processName);
3396        if (activity != null && activity.shortComponentName != null) {
3397            info.append(" (").append(activity.shortComponentName).append(")");
3398        }
3399        info.append("\n");
3400        if (annotation != null) {
3401            info.append("Reason: ").append(annotation).append("\n");
3402        }
3403        if (parent != null && parent != activity) {
3404            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3405        }
3406
3407        final ProcessStats processStats = new ProcessStats(true);
3408
3409        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3410
3411        String cpuInfo = null;
3412        if (MONITOR_CPU_USAGE) {
3413            updateCpuStatsNow();
3414            synchronized (mProcessStatsThread) {
3415                cpuInfo = mProcessStats.printCurrentState(anrTime);
3416            }
3417            info.append(processStats.printCurrentLoad());
3418            info.append(cpuInfo);
3419        }
3420
3421        info.append(processStats.printCurrentState(anrTime));
3422
3423        Slog.e(TAG, info.toString());
3424        if (tracesFile == null) {
3425            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3426            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3427        }
3428
3429        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3430                cpuInfo, tracesFile, null);
3431
3432        if (mController != null) {
3433            try {
3434                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3435                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3436                if (res != 0) {
3437                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3438                    return;
3439                }
3440            } catch (RemoteException e) {
3441                mController = null;
3442                Watchdog.getInstance().setActivityController(null);
3443            }
3444        }
3445
3446        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3447        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3448                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3449
3450        synchronized (this) {
3451            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3452                Slog.w(TAG, "Killing " + app + ": background ANR");
3453                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3454                        app.processName, app.setAdj, "background ANR");
3455                Process.killProcessQuiet(app.pid);
3456                return;
3457            }
3458
3459            // Set the app's notResponding state, and look up the errorReportReceiver
3460            makeAppNotRespondingLocked(app,
3461                    activity != null ? activity.shortComponentName : null,
3462                    annotation != null ? "ANR " + annotation : "ANR",
3463                    info.toString());
3464
3465            // Bring up the infamous App Not Responding dialog
3466            Message msg = Message.obtain();
3467            HashMap map = new HashMap();
3468            msg.what = SHOW_NOT_RESPONDING_MSG;
3469            msg.obj = map;
3470            msg.arg1 = aboveSystem ? 1 : 0;
3471            map.put("app", app);
3472            if (activity != null) {
3473                map.put("activity", activity);
3474            }
3475
3476            mHandler.sendMessage(msg);
3477        }
3478    }
3479
3480    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3481        if (!mLaunchWarningShown) {
3482            mLaunchWarningShown = true;
3483            mHandler.post(new Runnable() {
3484                @Override
3485                public void run() {
3486                    synchronized (ActivityManagerService.this) {
3487                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3488                        d.show();
3489                        mHandler.postDelayed(new Runnable() {
3490                            @Override
3491                            public void run() {
3492                                synchronized (ActivityManagerService.this) {
3493                                    d.dismiss();
3494                                    mLaunchWarningShown = false;
3495                                }
3496                            }
3497                        }, 4000);
3498                    }
3499                }
3500            });
3501        }
3502    }
3503
3504    public boolean clearApplicationUserData(final String packageName,
3505            final IPackageDataObserver observer, int userId) {
3506        enforceNotIsolatedCaller("clearApplicationUserData");
3507        int uid = Binder.getCallingUid();
3508        int pid = Binder.getCallingPid();
3509        userId = handleIncomingUser(pid, uid,
3510                userId, false, true, "clearApplicationUserData", null);
3511        long callingId = Binder.clearCallingIdentity();
3512        try {
3513            IPackageManager pm = AppGlobals.getPackageManager();
3514            int pkgUid = -1;
3515            synchronized(this) {
3516                try {
3517                    pkgUid = pm.getPackageUid(packageName, userId);
3518                } catch (RemoteException e) {
3519                }
3520                if (pkgUid == -1) {
3521                    Slog.w(TAG, "Invalid packageName: " + packageName);
3522                    if (observer != null) {
3523                        try {
3524                            observer.onRemoveCompleted(packageName, false);
3525                        } catch (RemoteException e) {
3526                            Slog.i(TAG, "Observer no longer exists.");
3527                        }
3528                    }
3529                    return false;
3530                }
3531                if (uid == pkgUid || checkComponentPermission(
3532                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3533                        pid, uid, -1, true)
3534                        == PackageManager.PERMISSION_GRANTED) {
3535                    forceStopPackageLocked(packageName, pkgUid);
3536                } else {
3537                    throw new SecurityException(pid+" does not have permission:"+
3538                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3539                                    "for process:"+packageName);
3540                }
3541            }
3542
3543            try {
3544                //clear application user data
3545                pm.clearApplicationUserData(packageName, observer, userId);
3546                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3547                        Uri.fromParts("package", packageName, null));
3548                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3549                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3550                        null, null, 0, null, null, null, false, false, userId);
3551            } catch (RemoteException e) {
3552            }
3553        } finally {
3554            Binder.restoreCallingIdentity(callingId);
3555        }
3556        return true;
3557    }
3558
3559    public void killBackgroundProcesses(final String packageName, int userId) {
3560        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3561                != PackageManager.PERMISSION_GRANTED &&
3562                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3563                        != PackageManager.PERMISSION_GRANTED) {
3564            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3565                    + Binder.getCallingPid()
3566                    + ", uid=" + Binder.getCallingUid()
3567                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3568            Slog.w(TAG, msg);
3569            throw new SecurityException(msg);
3570        }
3571
3572        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3573                userId, true, true, "killBackgroundProcesses", null);
3574        long callingId = Binder.clearCallingIdentity();
3575        try {
3576            IPackageManager pm = AppGlobals.getPackageManager();
3577            synchronized(this) {
3578                int appId = -1;
3579                try {
3580                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3581                } catch (RemoteException e) {
3582                }
3583                if (appId == -1) {
3584                    Slog.w(TAG, "Invalid packageName: " + packageName);
3585                    return;
3586                }
3587                killPackageProcessesLocked(packageName, appId, userId,
3588                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3589            }
3590        } finally {
3591            Binder.restoreCallingIdentity(callingId);
3592        }
3593    }
3594
3595    public void killAllBackgroundProcesses() {
3596        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3597                != PackageManager.PERMISSION_GRANTED) {
3598            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3599                    + Binder.getCallingPid()
3600                    + ", uid=" + Binder.getCallingUid()
3601                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3602            Slog.w(TAG, msg);
3603            throw new SecurityException(msg);
3604        }
3605
3606        long callingId = Binder.clearCallingIdentity();
3607        try {
3608            synchronized(this) {
3609                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3610                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3611                    final int NA = apps.size();
3612                    for (int ia=0; ia<NA; ia++) {
3613                        ProcessRecord app = apps.valueAt(ia);
3614                        if (app.persistent) {
3615                            // we don't kill persistent processes
3616                            continue;
3617                        }
3618                        if (app.removed) {
3619                            procs.add(app);
3620                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3621                            app.removed = true;
3622                            procs.add(app);
3623                        }
3624                    }
3625                }
3626
3627                int N = procs.size();
3628                for (int i=0; i<N; i++) {
3629                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3630                }
3631            }
3632        } finally {
3633            Binder.restoreCallingIdentity(callingId);
3634        }
3635    }
3636
3637    public void forceStopPackage(final String packageName, int userId) {
3638        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3639                != PackageManager.PERMISSION_GRANTED) {
3640            String msg = "Permission Denial: forceStopPackage() from pid="
3641                    + Binder.getCallingPid()
3642                    + ", uid=" + Binder.getCallingUid()
3643                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3644            Slog.w(TAG, msg);
3645            throw new SecurityException(msg);
3646        }
3647        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3648                userId, true, true, "forceStopPackage", null);
3649        long callingId = Binder.clearCallingIdentity();
3650        try {
3651            IPackageManager pm = AppGlobals.getPackageManager();
3652            synchronized(this) {
3653                int[] users = userId == UserHandle.USER_ALL
3654                        ? getUsersLocked() : new int[] { userId };
3655                for (int user : users) {
3656                    int pkgUid = -1;
3657                    try {
3658                        pkgUid = pm.getPackageUid(packageName, user);
3659                    } catch (RemoteException e) {
3660                    }
3661                    if (pkgUid == -1) {
3662                        Slog.w(TAG, "Invalid packageName: " + packageName);
3663                        continue;
3664                    }
3665                    try {
3666                        pm.setPackageStoppedState(packageName, true, user);
3667                    } catch (RemoteException e) {
3668                    } catch (IllegalArgumentException e) {
3669                        Slog.w(TAG, "Failed trying to unstop package "
3670                                + packageName + ": " + e);
3671                    }
3672                    if (isUserRunningLocked(user, false)) {
3673                        forceStopPackageLocked(packageName, pkgUid);
3674                    }
3675                }
3676            }
3677        } finally {
3678            Binder.restoreCallingIdentity(callingId);
3679        }
3680    }
3681
3682    /*
3683     * The pkg name and app id have to be specified.
3684     */
3685    public void killApplicationWithAppId(String pkg, int appid) {
3686        if (pkg == null) {
3687            return;
3688        }
3689        // Make sure the uid is valid.
3690        if (appid < 0) {
3691            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3692            return;
3693        }
3694        int callerUid = Binder.getCallingUid();
3695        // Only the system server can kill an application
3696        if (callerUid == Process.SYSTEM_UID) {
3697            // Post an aysnc message to kill the application
3698            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3699            msg.arg1 = appid;
3700            msg.arg2 = 0;
3701            msg.obj = pkg;
3702            mHandler.sendMessage(msg);
3703        } else {
3704            throw new SecurityException(callerUid + " cannot kill pkg: " +
3705                    pkg);
3706        }
3707    }
3708
3709    public void closeSystemDialogs(String reason) {
3710        enforceNotIsolatedCaller("closeSystemDialogs");
3711
3712        final int pid = Binder.getCallingPid();
3713        final int uid = Binder.getCallingUid();
3714        final long origId = Binder.clearCallingIdentity();
3715        try {
3716            synchronized (this) {
3717                // Only allow this from foreground processes, so that background
3718                // applications can't abuse it to prevent system UI from being shown.
3719                if (uid >= Process.FIRST_APPLICATION_UID) {
3720                    ProcessRecord proc;
3721                    synchronized (mPidsSelfLocked) {
3722                        proc = mPidsSelfLocked.get(pid);
3723                    }
3724                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3725                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3726                                + " from background process " + proc);
3727                        return;
3728                    }
3729                }
3730                closeSystemDialogsLocked(reason);
3731            }
3732        } finally {
3733            Binder.restoreCallingIdentity(origId);
3734        }
3735    }
3736
3737    void closeSystemDialogsLocked(String reason) {
3738        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3740                | Intent.FLAG_RECEIVER_FOREGROUND);
3741        if (reason != null) {
3742            intent.putExtra("reason", reason);
3743        }
3744        mWindowManager.closeSystemDialogs(reason);
3745
3746        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3747            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3748            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3749                r.stack.finishActivityLocked(r, i,
3750                        Activity.RESULT_CANCELED, null, "close-sys", true);
3751            }
3752        }
3753
3754        broadcastIntentLocked(null, null, intent, null,
3755                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
3756                Process.SYSTEM_UID, UserHandle.USER_ALL);
3757    }
3758
3759    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3760            throws RemoteException {
3761        enforceNotIsolatedCaller("getProcessMemoryInfo");
3762        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3763        for (int i=pids.length-1; i>=0; i--) {
3764            infos[i] = new Debug.MemoryInfo();
3765            Debug.getMemoryInfo(pids[i], infos[i]);
3766        }
3767        return infos;
3768    }
3769
3770    public long[] getProcessPss(int[] pids) throws RemoteException {
3771        enforceNotIsolatedCaller("getProcessPss");
3772        long[] pss = new long[pids.length];
3773        for (int i=pids.length-1; i>=0; i--) {
3774            pss[i] = Debug.getPss(pids[i]);
3775        }
3776        return pss;
3777    }
3778
3779    public void killApplicationProcess(String processName, int uid) {
3780        if (processName == null) {
3781            return;
3782        }
3783
3784        int callerUid = Binder.getCallingUid();
3785        // Only the system server can kill an application
3786        if (callerUid == Process.SYSTEM_UID) {
3787            synchronized (this) {
3788                ProcessRecord app = getProcessRecordLocked(processName, uid);
3789                if (app != null && app.thread != null) {
3790                    try {
3791                        app.thread.scheduleSuicide();
3792                    } catch (RemoteException e) {
3793                        // If the other end already died, then our work here is done.
3794                    }
3795                } else {
3796                    Slog.w(TAG, "Process/uid not found attempting kill of "
3797                            + processName + " / " + uid);
3798                }
3799            }
3800        } else {
3801            throw new SecurityException(callerUid + " cannot kill app process: " +
3802                    processName);
3803        }
3804    }
3805
3806    private void forceStopPackageLocked(final String packageName, int uid) {
3807        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3808                false, true, false, UserHandle.getUserId(uid));
3809        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3810                Uri.fromParts("package", packageName, null));
3811        if (!mProcessesReady) {
3812            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3813                    | Intent.FLAG_RECEIVER_FOREGROUND);
3814        }
3815        intent.putExtra(Intent.EXTRA_UID, uid);
3816        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3817        broadcastIntentLocked(null, null, intent,
3818                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
3819                false, false,
3820                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3821    }
3822
3823    private void forceStopUserLocked(int userId) {
3824        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3825        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3826        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3827                | Intent.FLAG_RECEIVER_FOREGROUND);
3828        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3829        broadcastIntentLocked(null, null, intent,
3830                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
3831                false, false,
3832                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3833    }
3834
3835    private final boolean killPackageProcessesLocked(String packageName, int appId,
3836            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3837            boolean doit, boolean evenPersistent, String reason) {
3838        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3839
3840        // Remove all processes this package may have touched: all with the
3841        // same UID (except for the system or root user), and all whose name
3842        // matches the package name.
3843        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3844        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3845            final int NA = apps.size();
3846            for (int ia=0; ia<NA; ia++) {
3847                ProcessRecord app = apps.valueAt(ia);
3848                if (app.persistent && !evenPersistent) {
3849                    // we don't kill persistent processes
3850                    continue;
3851                }
3852                if (app.removed) {
3853                    if (doit) {
3854                        procs.add(app);
3855                    }
3856                    continue;
3857                }
3858
3859                // Skip process if it doesn't meet our oom adj requirement.
3860                if (app.setAdj < minOomAdj) {
3861                    continue;
3862                }
3863
3864                // If no package is specified, we call all processes under the
3865                // give user id.
3866                if (packageName == null) {
3867                    if (app.userId != userId) {
3868                        continue;
3869                    }
3870                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
3871                        continue;
3872                    }
3873                // Package has been specified, we want to hit all processes
3874                // that match it.  We need to qualify this by the processes
3875                // that are running under the specified app and user ID.
3876                } else {
3877                    if (UserHandle.getAppId(app.uid) != appId) {
3878                        continue;
3879                    }
3880                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3881                        continue;
3882                    }
3883                    if (!app.pkgList.contains(packageName)) {
3884                        continue;
3885                    }
3886                }
3887
3888                // Process has passed all conditions, kill it!
3889                if (!doit) {
3890                    return true;
3891                }
3892                app.removed = true;
3893                procs.add(app);
3894            }
3895        }
3896
3897        int N = procs.size();
3898        for (int i=0; i<N; i++) {
3899            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3900        }
3901        return N > 0;
3902    }
3903
3904    private final boolean forceStopPackageLocked(String name, int appId,
3905            boolean callerWillRestart, boolean purgeCache, boolean doit,
3906            boolean evenPersistent, int userId) {
3907        int i;
3908        int N;
3909
3910        if (userId == UserHandle.USER_ALL && name == null) {
3911            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3912        }
3913
3914        if (appId < 0 && name != null) {
3915            try {
3916                appId = UserHandle.getAppId(
3917                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3918            } catch (RemoteException e) {
3919            }
3920        }
3921
3922        if (doit) {
3923            if (name != null) {
3924                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3925                        + " user=" + userId);
3926            } else {
3927                Slog.i(TAG, "Force stopping user " + userId);
3928            }
3929
3930            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3931            while (badApps.hasNext()) {
3932                SparseArray<Long> ba = badApps.next();
3933                for (i=ba.size()-1; i>=0; i--) {
3934                    boolean remove = false;
3935                    final int entUid = ba.keyAt(i);
3936                    if (name != null) {
3937                        if (userId == UserHandle.USER_ALL) {
3938                            if (UserHandle.getAppId(entUid) == appId) {
3939                                remove = true;
3940                            }
3941                        } else {
3942                            if (entUid == UserHandle.getUid(userId, appId)) {
3943                                remove = true;
3944                            }
3945                        }
3946                    } else if (UserHandle.getUserId(entUid) == userId) {
3947                        remove = true;
3948                    }
3949                    if (remove) {
3950                        ba.removeAt(i);
3951                    }
3952                }
3953                if (ba.size() == 0) {
3954                    badApps.remove();
3955                }
3956            }
3957        }
3958
3959        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3960                -100, callerWillRestart, true, doit, evenPersistent,
3961                name == null ? ("force stop user " + userId) : ("force stop " + name));
3962
3963        TaskRecord lastTask = null;
3964        for (i=0; i<mMainStack.mHistory.size(); i++) {
3965            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3966            final boolean samePackage = r.packageName.equals(name)
3967                    || (name == null && r.userId == userId);
3968            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3969                    && (samePackage || r.task == lastTask)
3970                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3971                if (!doit) {
3972                    if (r.finishing) {
3973                        // If this activity is just finishing, then it is not
3974                        // interesting as far as something to stop.
3975                        continue;
3976                    }
3977                    return true;
3978                }
3979                didSomething = true;
3980                Slog.i(TAG, "  Force finishing activity " + r);
3981                if (samePackage) {
3982                    if (r.app != null) {
3983                        r.app.removed = true;
3984                    }
3985                    r.app = null;
3986                }
3987                lastTask = r.task;
3988                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3989                        null, "force-stop", true)) {
3990                    i--;
3991                }
3992            }
3993        }
3994
3995        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3996            if (!doit) {
3997                return true;
3998            }
3999            didSomething = true;
4000        }
4001
4002        if (name == null) {
4003            // Remove all sticky broadcasts from this user.
4004            mStickyBroadcasts.remove(userId);
4005        }
4006
4007        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4008        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4009                userId, providers)) {
4010            if (!doit) {
4011                return true;
4012            }
4013            didSomething = true;
4014        }
4015        N = providers.size();
4016        for (i=0; i<N; i++) {
4017            removeDyingProviderLocked(null, providers.get(i), true);
4018        }
4019
4020        if (name == null) {
4021            // Remove pending intents.  For now we only do this when force
4022            // stopping users, because we have some problems when doing this
4023            // for packages -- app widgets are not currently cleaned up for
4024            // such packages, so they can be left with bad pending intents.
4025            if (mIntentSenderRecords.size() > 0) {
4026                Iterator<WeakReference<PendingIntentRecord>> it
4027                        = mIntentSenderRecords.values().iterator();
4028                while (it.hasNext()) {
4029                    WeakReference<PendingIntentRecord> wpir = it.next();
4030                    if (wpir == null) {
4031                        it.remove();
4032                        continue;
4033                    }
4034                    PendingIntentRecord pir = wpir.get();
4035                    if (pir == null) {
4036                        it.remove();
4037                        continue;
4038                    }
4039                    if (name == null) {
4040                        // Stopping user, remove all objects for the user.
4041                        if (pir.key.userId != userId) {
4042                            // Not the same user, skip it.
4043                            continue;
4044                        }
4045                    } else {
4046                        if (UserHandle.getAppId(pir.uid) != appId) {
4047                            // Different app id, skip it.
4048                            continue;
4049                        }
4050                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4051                            // Different user, skip it.
4052                            continue;
4053                        }
4054                        if (!pir.key.packageName.equals(name)) {
4055                            // Different package, skip it.
4056                            continue;
4057                        }
4058                    }
4059                    if (!doit) {
4060                        return true;
4061                    }
4062                    didSomething = true;
4063                    it.remove();
4064                    pir.canceled = true;
4065                    if (pir.key.activity != null) {
4066                        pir.key.activity.pendingResults.remove(pir.ref);
4067                    }
4068                }
4069            }
4070        }
4071
4072        if (doit) {
4073            if (purgeCache && name != null) {
4074                AttributeCache ac = AttributeCache.instance();
4075                if (ac != null) {
4076                    ac.removePackage(name);
4077                }
4078            }
4079            if (mBooted) {
4080                mMainStack.resumeTopActivityLocked(null);
4081                mMainStack.scheduleIdleLocked();
4082            }
4083        }
4084
4085        return didSomething;
4086    }
4087
4088    private final boolean removeProcessLocked(ProcessRecord app,
4089            boolean callerWillRestart, boolean allowRestart, String reason) {
4090        final String name = app.processName;
4091        final int uid = app.uid;
4092        if (DEBUG_PROCESSES) Slog.d(
4093            TAG, "Force removing proc " + app.toShortString() + " (" + name
4094            + "/" + uid + ")");
4095
4096        mProcessNames.remove(name, uid);
4097        mIsolatedProcesses.remove(app.uid);
4098        if (mHeavyWeightProcess == app) {
4099            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4100                    mHeavyWeightProcess.userId, 0));
4101            mHeavyWeightProcess = null;
4102        }
4103        boolean needRestart = false;
4104        if (app.pid > 0 && app.pid != MY_PID) {
4105            int pid = app.pid;
4106            synchronized (mPidsSelfLocked) {
4107                mPidsSelfLocked.remove(pid);
4108                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4109            }
4110            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4111            handleAppDiedLocked(app, true, allowRestart);
4112            mLruProcesses.remove(app);
4113            Process.killProcessQuiet(pid);
4114
4115            if (app.persistent && !app.isolated) {
4116                if (!callerWillRestart) {
4117                    addAppLocked(app.info, false);
4118                } else {
4119                    needRestart = true;
4120                }
4121            }
4122        } else {
4123            mRemovedProcesses.add(app);
4124        }
4125
4126        return needRestart;
4127    }
4128
4129    private final void processStartTimedOutLocked(ProcessRecord app) {
4130        final int pid = app.pid;
4131        boolean gone = false;
4132        synchronized (mPidsSelfLocked) {
4133            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4134            if (knownApp != null && knownApp.thread == null) {
4135                mPidsSelfLocked.remove(pid);
4136                gone = true;
4137            }
4138        }
4139
4140        if (gone) {
4141            Slog.w(TAG, "Process " + app + " failed to attach");
4142            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4143                    pid, app.uid, app.processName);
4144            mProcessNames.remove(app.processName, app.uid);
4145            mIsolatedProcesses.remove(app.uid);
4146            if (mHeavyWeightProcess == app) {
4147                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4148                        mHeavyWeightProcess.userId, 0));
4149                mHeavyWeightProcess = null;
4150            }
4151            // Take care of any launching providers waiting for this process.
4152            checkAppInLaunchingProvidersLocked(app, true);
4153            // Take care of any services that are waiting for the process.
4154            mServices.processStartTimedOutLocked(app);
4155            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4156                    app.processName, app.setAdj, "start timeout");
4157            Process.killProcessQuiet(pid);
4158            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4159                Slog.w(TAG, "Unattached app died before backup, skipping");
4160                try {
4161                    IBackupManager bm = IBackupManager.Stub.asInterface(
4162                            ServiceManager.getService(Context.BACKUP_SERVICE));
4163                    bm.agentDisconnected(app.info.packageName);
4164                } catch (RemoteException e) {
4165                    // Can't happen; the backup manager is local
4166                }
4167            }
4168            if (isPendingBroadcastProcessLocked(pid)) {
4169                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4170                skipPendingBroadcastLocked(pid);
4171            }
4172        } else {
4173            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4174        }
4175    }
4176
4177    private final boolean attachApplicationLocked(IApplicationThread thread,
4178            int pid) {
4179
4180        // Find the application record that is being attached...  either via
4181        // the pid if we are running in multiple processes, or just pull the
4182        // next app record if we are emulating process with anonymous threads.
4183        ProcessRecord app;
4184        if (pid != MY_PID && pid >= 0) {
4185            synchronized (mPidsSelfLocked) {
4186                app = mPidsSelfLocked.get(pid);
4187            }
4188        } else {
4189            app = null;
4190        }
4191
4192        if (app == null) {
4193            Slog.w(TAG, "No pending application record for pid " + pid
4194                    + " (IApplicationThread " + thread + "); dropping process");
4195            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4196            if (pid > 0 && pid != MY_PID) {
4197                Process.killProcessQuiet(pid);
4198            } else {
4199                try {
4200                    thread.scheduleExit();
4201                } catch (Exception e) {
4202                    // Ignore exceptions.
4203                }
4204            }
4205            return false;
4206        }
4207
4208        // If this application record is still attached to a previous
4209        // process, clean it up now.
4210        if (app.thread != null) {
4211            handleAppDiedLocked(app, true, true);
4212        }
4213
4214        // Tell the process all about itself.
4215
4216        if (localLOGV) Slog.v(
4217                TAG, "Binding process pid " + pid + " to record " + app);
4218
4219        String processName = app.processName;
4220        try {
4221            AppDeathRecipient adr = new AppDeathRecipient(
4222                    app, pid, thread);
4223            thread.asBinder().linkToDeath(adr, 0);
4224            app.deathRecipient = adr;
4225        } catch (RemoteException e) {
4226            app.resetPackageList();
4227            startProcessLocked(app, "link fail", processName);
4228            return false;
4229        }
4230
4231        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4232
4233        app.thread = thread;
4234        app.curAdj = app.setAdj = -100;
4235        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4236        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4237        app.forcingToForeground = null;
4238        app.foregroundServices = false;
4239        app.hasShownUi = false;
4240        app.debugging = false;
4241
4242        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4243
4244        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4245        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4246
4247        if (!normalMode) {
4248            Slog.i(TAG, "Launching preboot mode app: " + app);
4249        }
4250
4251        if (localLOGV) Slog.v(
4252            TAG, "New app record " + app
4253            + " thread=" + thread.asBinder() + " pid=" + pid);
4254        try {
4255            int testMode = IApplicationThread.DEBUG_OFF;
4256            if (mDebugApp != null && mDebugApp.equals(processName)) {
4257                testMode = mWaitForDebugger
4258                    ? IApplicationThread.DEBUG_WAIT
4259                    : IApplicationThread.DEBUG_ON;
4260                app.debugging = true;
4261                if (mDebugTransient) {
4262                    mDebugApp = mOrigDebugApp;
4263                    mWaitForDebugger = mOrigWaitForDebugger;
4264                }
4265            }
4266            String profileFile = app.instrumentationProfileFile;
4267            ParcelFileDescriptor profileFd = null;
4268            boolean profileAutoStop = false;
4269            if (mProfileApp != null && mProfileApp.equals(processName)) {
4270                mProfileProc = app;
4271                profileFile = mProfileFile;
4272                profileFd = mProfileFd;
4273                profileAutoStop = mAutoStopProfiler;
4274            }
4275            boolean enableOpenGlTrace = false;
4276            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4277                enableOpenGlTrace = true;
4278                mOpenGlTraceApp = null;
4279            }
4280
4281            // If the app is being launched for restore or full backup, set it up specially
4282            boolean isRestrictedBackupMode = false;
4283            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4284                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4285                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4286                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4287            }
4288
4289            ensurePackageDexOpt(app.instrumentationInfo != null
4290                    ? app.instrumentationInfo.packageName
4291                    : app.info.packageName);
4292            if (app.instrumentationClass != null) {
4293                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4294            }
4295            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4296                    + processName + " with config " + mConfiguration);
4297            ApplicationInfo appInfo = app.instrumentationInfo != null
4298                    ? app.instrumentationInfo : app.info;
4299            app.compat = compatibilityInfoForPackageLocked(appInfo);
4300            if (profileFd != null) {
4301                profileFd = profileFd.dup();
4302            }
4303            thread.bindApplication(processName, appInfo, providers,
4304                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4305                    app.instrumentationArguments, app.instrumentationWatcher,
4306                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4307                    isRestrictedBackupMode || !normalMode, app.persistent,
4308                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4309                    mCoreSettingsObserver.getCoreSettingsLocked());
4310            updateLruProcessLocked(app, false);
4311            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4312        } catch (Exception e) {
4313            // todo: Yikes!  What should we do?  For now we will try to
4314            // start another process, but that could easily get us in
4315            // an infinite loop of restarting processes...
4316            Slog.w(TAG, "Exception thrown during bind!", e);
4317
4318            app.resetPackageList();
4319            app.unlinkDeathRecipient();
4320            startProcessLocked(app, "bind fail", processName);
4321            return false;
4322        }
4323
4324        // Remove this record from the list of starting applications.
4325        mPersistentStartingProcesses.remove(app);
4326        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4327                "Attach application locked removing on hold: " + app);
4328        mProcessesOnHold.remove(app);
4329
4330        boolean badApp = false;
4331        boolean didSomething = false;
4332
4333        // See if the top visible activity is waiting to run in this process...
4334        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4335        if (hr != null && normalMode) {
4336            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4337                    && processName.equals(hr.processName)) {
4338                try {
4339                    if (mHeadless) {
4340                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4341                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4342                        didSomething = true;
4343                    }
4344                } catch (Exception e) {
4345                    Slog.w(TAG, "Exception in new application when starting activity "
4346                          + hr.intent.getComponent().flattenToShortString(), e);
4347                    badApp = true;
4348                }
4349            } else {
4350                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4351            }
4352        }
4353
4354        // Find any services that should be running in this process...
4355        if (!badApp) {
4356            try {
4357                didSomething |= mServices.attachApplicationLocked(app, processName);
4358            } catch (Exception e) {
4359                badApp = true;
4360            }
4361        }
4362
4363        // Check if a next-broadcast receiver is in this process...
4364        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4365            try {
4366                didSomething = sendPendingBroadcastsLocked(app);
4367            } catch (Exception e) {
4368                // If the app died trying to launch the receiver we declare it 'bad'
4369                badApp = true;
4370            }
4371        }
4372
4373        // Check whether the next backup agent is in this process...
4374        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4375            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4376            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4377            try {
4378                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4379                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4380                        mBackupTarget.backupMode);
4381            } catch (Exception e) {
4382                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4383                e.printStackTrace();
4384            }
4385        }
4386
4387        if (badApp) {
4388            // todo: Also need to kill application to deal with all
4389            // kinds of exceptions.
4390            handleAppDiedLocked(app, false, true);
4391            return false;
4392        }
4393
4394        if (!didSomething) {
4395            updateOomAdjLocked();
4396        }
4397
4398        return true;
4399    }
4400
4401    public final void attachApplication(IApplicationThread thread) {
4402        synchronized (this) {
4403            int callingPid = Binder.getCallingPid();
4404            final long origId = Binder.clearCallingIdentity();
4405            attachApplicationLocked(thread, callingPid);
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4411        final long origId = Binder.clearCallingIdentity();
4412        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4413        if (stopProfiling) {
4414            synchronized (this) {
4415                if (mProfileProc == r.app) {
4416                    if (mProfileFd != null) {
4417                        try {
4418                            mProfileFd.close();
4419                        } catch (IOException e) {
4420                        }
4421                        clearProfilerLocked();
4422                    }
4423                }
4424            }
4425        }
4426        Binder.restoreCallingIdentity(origId);
4427    }
4428
4429    void enableScreenAfterBoot() {
4430        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4431                SystemClock.uptimeMillis());
4432        mWindowManager.enableScreenAfterBoot();
4433
4434        synchronized (this) {
4435            updateEventDispatchingLocked();
4436        }
4437    }
4438
4439    public void showBootMessage(final CharSequence msg, final boolean always) {
4440        enforceNotIsolatedCaller("showBootMessage");
4441        mWindowManager.showBootMessage(msg, always);
4442    }
4443
4444    public void dismissKeyguardOnNextActivity() {
4445        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4446        final long token = Binder.clearCallingIdentity();
4447        try {
4448            synchronized (this) {
4449                if (mLockScreenShown) {
4450                    mLockScreenShown = false;
4451                    comeOutOfSleepIfNeededLocked();
4452                }
4453                mMainStack.dismissKeyguardOnNextActivityLocked();
4454            }
4455        } finally {
4456            Binder.restoreCallingIdentity(token);
4457        }
4458    }
4459
4460    final void finishBooting() {
4461        IntentFilter pkgFilter = new IntentFilter();
4462        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4463        pkgFilter.addDataScheme("package");
4464        mContext.registerReceiver(new BroadcastReceiver() {
4465            @Override
4466            public void onReceive(Context context, Intent intent) {
4467                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4468                if (pkgs != null) {
4469                    for (String pkg : pkgs) {
4470                        synchronized (ActivityManagerService.this) {
4471                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4472                                setResultCode(Activity.RESULT_OK);
4473                                return;
4474                            }
4475                        }
4476                    }
4477                }
4478            }
4479        }, pkgFilter);
4480
4481        synchronized (this) {
4482            // Ensure that any processes we had put on hold are now started
4483            // up.
4484            final int NP = mProcessesOnHold.size();
4485            if (NP > 0) {
4486                ArrayList<ProcessRecord> procs =
4487                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4488                for (int ip=0; ip<NP; ip++) {
4489                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4490                            + procs.get(ip));
4491                    startProcessLocked(procs.get(ip), "on-hold", null);
4492                }
4493            }
4494
4495            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4496                // Start looking for apps that are abusing wake locks.
4497                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4498                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4499                // Tell anyone interested that we are done booting!
4500                SystemProperties.set("sys.boot_completed", "1");
4501                SystemProperties.set("dev.bootcomplete", "1");
4502                for (int i=0; i<mStartedUsers.size(); i++) {
4503                    UserStartedState uss = mStartedUsers.valueAt(i);
4504                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4505                        uss.mState = UserStartedState.STATE_RUNNING;
4506                        final int userId = mStartedUsers.keyAt(i);
4507                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4508                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4509                        broadcastIntentLocked(null, null, intent,
4510                                null, null, 0, null, null,
4511                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4512                                AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID,
4513                                userId);
4514                    }
4515                }
4516            }
4517        }
4518    }
4519
4520    final void ensureBootCompleted() {
4521        boolean booting;
4522        boolean enableScreen;
4523        synchronized (this) {
4524            booting = mBooting;
4525            mBooting = false;
4526            enableScreen = !mBooted;
4527            mBooted = true;
4528        }
4529
4530        if (booting) {
4531            finishBooting();
4532        }
4533
4534        if (enableScreen) {
4535            enableScreenAfterBoot();
4536        }
4537    }
4538
4539    public final void activityResumed(IBinder token) {
4540        final long origId = Binder.clearCallingIdentity();
4541        mMainStack.activityResumed(token);
4542        Binder.restoreCallingIdentity(origId);
4543    }
4544
4545    public final void activityPaused(IBinder token) {
4546        final long origId = Binder.clearCallingIdentity();
4547        mMainStack.activityPaused(token, false);
4548        Binder.restoreCallingIdentity(origId);
4549    }
4550
4551    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4552            CharSequence description) {
4553        if (localLOGV) Slog.v(
4554            TAG, "Activity stopped: token=" + token);
4555
4556        // Refuse possible leaked file descriptors
4557        if (icicle != null && icicle.hasFileDescriptors()) {
4558            throw new IllegalArgumentException("File descriptors passed in Bundle");
4559        }
4560
4561        ActivityRecord r = null;
4562
4563        final long origId = Binder.clearCallingIdentity();
4564
4565        synchronized (this) {
4566            r = mMainStack.isInStackLocked(token);
4567            if (r != null) {
4568                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4569            }
4570        }
4571
4572        if (r != null) {
4573            sendPendingThumbnail(r, null, null, null, false);
4574        }
4575
4576        trimApplications();
4577
4578        Binder.restoreCallingIdentity(origId);
4579    }
4580
4581    public final void activityDestroyed(IBinder token) {
4582        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4583        mMainStack.activityDestroyed(token);
4584    }
4585
4586    public String getCallingPackage(IBinder token) {
4587        synchronized (this) {
4588            ActivityRecord r = getCallingRecordLocked(token);
4589            return r != null ? r.info.packageName : null;
4590        }
4591    }
4592
4593    public ComponentName getCallingActivity(IBinder token) {
4594        synchronized (this) {
4595            ActivityRecord r = getCallingRecordLocked(token);
4596            return r != null ? r.intent.getComponent() : null;
4597        }
4598    }
4599
4600    private ActivityRecord getCallingRecordLocked(IBinder token) {
4601        ActivityRecord r = mMainStack.isInStackLocked(token);
4602        if (r == null) {
4603            return null;
4604        }
4605        return r.resultTo;
4606    }
4607
4608    public ComponentName getActivityClassForToken(IBinder token) {
4609        synchronized(this) {
4610            ActivityRecord r = mMainStack.isInStackLocked(token);
4611            if (r == null) {
4612                return null;
4613            }
4614            return r.intent.getComponent();
4615        }
4616    }
4617
4618    public String getPackageForToken(IBinder token) {
4619        synchronized(this) {
4620            ActivityRecord r = mMainStack.isInStackLocked(token);
4621            if (r == null) {
4622                return null;
4623            }
4624            return r.packageName;
4625        }
4626    }
4627
4628    public IIntentSender getIntentSender(int type,
4629            String packageName, IBinder token, String resultWho,
4630            int requestCode, Intent[] intents, String[] resolvedTypes,
4631            int flags, Bundle options, int userId) {
4632        enforceNotIsolatedCaller("getIntentSender");
4633        // Refuse possible leaked file descriptors
4634        if (intents != null) {
4635            if (intents.length < 1) {
4636                throw new IllegalArgumentException("Intents array length must be >= 1");
4637            }
4638            for (int i=0; i<intents.length; i++) {
4639                Intent intent = intents[i];
4640                if (intent != null) {
4641                    if (intent.hasFileDescriptors()) {
4642                        throw new IllegalArgumentException("File descriptors passed in Intent");
4643                    }
4644                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4645                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4646                        throw new IllegalArgumentException(
4647                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4648                    }
4649                    intents[i] = new Intent(intent);
4650                }
4651            }
4652            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4653                throw new IllegalArgumentException(
4654                        "Intent array length does not match resolvedTypes length");
4655            }
4656        }
4657        if (options != null) {
4658            if (options.hasFileDescriptors()) {
4659                throw new IllegalArgumentException("File descriptors passed in options");
4660            }
4661        }
4662
4663        synchronized(this) {
4664            int callingUid = Binder.getCallingUid();
4665            int origUserId = userId;
4666            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4667                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4668                    "getIntentSender", null);
4669            if (origUserId == UserHandle.USER_CURRENT) {
4670                // We don't want to evaluate this until the pending intent is
4671                // actually executed.  However, we do want to always do the
4672                // security checking for it above.
4673                userId = UserHandle.USER_CURRENT;
4674            }
4675            try {
4676                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4677                    int uid = AppGlobals.getPackageManager()
4678                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4679                    if (!UserHandle.isSameApp(callingUid, uid)) {
4680                        String msg = "Permission Denial: getIntentSender() from pid="
4681                            + Binder.getCallingPid()
4682                            + ", uid=" + Binder.getCallingUid()
4683                            + ", (need uid=" + uid + ")"
4684                            + " is not allowed to send as package " + packageName;
4685                        Slog.w(TAG, msg);
4686                        throw new SecurityException(msg);
4687                    }
4688                }
4689
4690                return getIntentSenderLocked(type, packageName, callingUid, userId,
4691                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4692
4693            } catch (RemoteException e) {
4694                throw new SecurityException(e);
4695            }
4696        }
4697    }
4698
4699    IIntentSender getIntentSenderLocked(int type, String packageName,
4700            int callingUid, int userId, IBinder token, String resultWho,
4701            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4702            Bundle options) {
4703        if (DEBUG_MU)
4704            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4705        ActivityRecord activity = null;
4706        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4707            activity = mMainStack.isInStackLocked(token);
4708            if (activity == null) {
4709                return null;
4710            }
4711            if (activity.finishing) {
4712                return null;
4713            }
4714        }
4715
4716        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4717        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4718        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4719        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4720                |PendingIntent.FLAG_UPDATE_CURRENT);
4721
4722        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4723                type, packageName, activity, resultWho,
4724                requestCode, intents, resolvedTypes, flags, options, userId);
4725        WeakReference<PendingIntentRecord> ref;
4726        ref = mIntentSenderRecords.get(key);
4727        PendingIntentRecord rec = ref != null ? ref.get() : null;
4728        if (rec != null) {
4729            if (!cancelCurrent) {
4730                if (updateCurrent) {
4731                    if (rec.key.requestIntent != null) {
4732                        rec.key.requestIntent.replaceExtras(intents != null ?
4733                                intents[intents.length - 1] : null);
4734                    }
4735                    if (intents != null) {
4736                        intents[intents.length-1] = rec.key.requestIntent;
4737                        rec.key.allIntents = intents;
4738                        rec.key.allResolvedTypes = resolvedTypes;
4739                    } else {
4740                        rec.key.allIntents = null;
4741                        rec.key.allResolvedTypes = null;
4742                    }
4743                }
4744                return rec;
4745            }
4746            rec.canceled = true;
4747            mIntentSenderRecords.remove(key);
4748        }
4749        if (noCreate) {
4750            return rec;
4751        }
4752        rec = new PendingIntentRecord(this, key, callingUid);
4753        mIntentSenderRecords.put(key, rec.ref);
4754        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4755            if (activity.pendingResults == null) {
4756                activity.pendingResults
4757                        = new HashSet<WeakReference<PendingIntentRecord>>();
4758            }
4759            activity.pendingResults.add(rec.ref);
4760        }
4761        return rec;
4762    }
4763
4764    public void cancelIntentSender(IIntentSender sender) {
4765        if (!(sender instanceof PendingIntentRecord)) {
4766            return;
4767        }
4768        synchronized(this) {
4769            PendingIntentRecord rec = (PendingIntentRecord)sender;
4770            try {
4771                int uid = AppGlobals.getPackageManager()
4772                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4773                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4774                    String msg = "Permission Denial: cancelIntentSender() from pid="
4775                        + Binder.getCallingPid()
4776                        + ", uid=" + Binder.getCallingUid()
4777                        + " is not allowed to cancel packges "
4778                        + rec.key.packageName;
4779                    Slog.w(TAG, msg);
4780                    throw new SecurityException(msg);
4781                }
4782            } catch (RemoteException e) {
4783                throw new SecurityException(e);
4784            }
4785            cancelIntentSenderLocked(rec, true);
4786        }
4787    }
4788
4789    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4790        rec.canceled = true;
4791        mIntentSenderRecords.remove(rec.key);
4792        if (cleanActivity && rec.key.activity != null) {
4793            rec.key.activity.pendingResults.remove(rec.ref);
4794        }
4795    }
4796
4797    public String getPackageForIntentSender(IIntentSender pendingResult) {
4798        if (!(pendingResult instanceof PendingIntentRecord)) {
4799            return null;
4800        }
4801        try {
4802            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4803            return res.key.packageName;
4804        } catch (ClassCastException e) {
4805        }
4806        return null;
4807    }
4808
4809    public int getUidForIntentSender(IIntentSender sender) {
4810        if (sender instanceof PendingIntentRecord) {
4811            try {
4812                PendingIntentRecord res = (PendingIntentRecord)sender;
4813                return res.uid;
4814            } catch (ClassCastException e) {
4815            }
4816        }
4817        return -1;
4818    }
4819
4820    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4821        if (!(pendingResult instanceof PendingIntentRecord)) {
4822            return false;
4823        }
4824        try {
4825            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4826            if (res.key.allIntents == null) {
4827                return false;
4828            }
4829            for (int i=0; i<res.key.allIntents.length; i++) {
4830                Intent intent = res.key.allIntents[i];
4831                if (intent.getPackage() != null && intent.getComponent() != null) {
4832                    return false;
4833                }
4834            }
4835            return true;
4836        } catch (ClassCastException e) {
4837        }
4838        return false;
4839    }
4840
4841    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4842        if (!(pendingResult instanceof PendingIntentRecord)) {
4843            return false;
4844        }
4845        try {
4846            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4847            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4848                return true;
4849            }
4850            return false;
4851        } catch (ClassCastException e) {
4852        }
4853        return false;
4854    }
4855
4856    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4857        if (!(pendingResult instanceof PendingIntentRecord)) {
4858            return null;
4859        }
4860        try {
4861            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4862            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4863        } catch (ClassCastException e) {
4864        }
4865        return null;
4866    }
4867
4868    public void setProcessLimit(int max) {
4869        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4870                "setProcessLimit()");
4871        synchronized (this) {
4872            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4873            mProcessLimitOverride = max;
4874        }
4875        trimApplications();
4876    }
4877
4878    public int getProcessLimit() {
4879        synchronized (this) {
4880            return mProcessLimitOverride;
4881        }
4882    }
4883
4884    void foregroundTokenDied(ForegroundToken token) {
4885        synchronized (ActivityManagerService.this) {
4886            synchronized (mPidsSelfLocked) {
4887                ForegroundToken cur
4888                    = mForegroundProcesses.get(token.pid);
4889                if (cur != token) {
4890                    return;
4891                }
4892                mForegroundProcesses.remove(token.pid);
4893                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4894                if (pr == null) {
4895                    return;
4896                }
4897                pr.forcingToForeground = null;
4898                pr.foregroundServices = false;
4899            }
4900            updateOomAdjLocked();
4901        }
4902    }
4903
4904    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4905        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4906                "setProcessForeground()");
4907        synchronized(this) {
4908            boolean changed = false;
4909
4910            synchronized (mPidsSelfLocked) {
4911                ProcessRecord pr = mPidsSelfLocked.get(pid);
4912                if (pr == null && isForeground) {
4913                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4914                    return;
4915                }
4916                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4917                if (oldToken != null) {
4918                    oldToken.token.unlinkToDeath(oldToken, 0);
4919                    mForegroundProcesses.remove(pid);
4920                    if (pr != null) {
4921                        pr.forcingToForeground = null;
4922                    }
4923                    changed = true;
4924                }
4925                if (isForeground && token != null) {
4926                    ForegroundToken newToken = new ForegroundToken() {
4927                        public void binderDied() {
4928                            foregroundTokenDied(this);
4929                        }
4930                    };
4931                    newToken.pid = pid;
4932                    newToken.token = token;
4933                    try {
4934                        token.linkToDeath(newToken, 0);
4935                        mForegroundProcesses.put(pid, newToken);
4936                        pr.forcingToForeground = token;
4937                        changed = true;
4938                    } catch (RemoteException e) {
4939                        // If the process died while doing this, we will later
4940                        // do the cleanup with the process death link.
4941                    }
4942                }
4943            }
4944
4945            if (changed) {
4946                updateOomAdjLocked();
4947            }
4948        }
4949    }
4950
4951    // =========================================================
4952    // PERMISSIONS
4953    // =========================================================
4954
4955    static class PermissionController extends IPermissionController.Stub {
4956        ActivityManagerService mActivityManagerService;
4957        PermissionController(ActivityManagerService activityManagerService) {
4958            mActivityManagerService = activityManagerService;
4959        }
4960
4961        public boolean checkPermission(String permission, int pid, int uid) {
4962            return mActivityManagerService.checkPermission(permission, pid,
4963                    uid) == PackageManager.PERMISSION_GRANTED;
4964        }
4965    }
4966
4967    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
4968        public int checkComponentPermission(String permission, int pid, int uid,
4969                int owningUid, boolean exported) {
4970            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
4971                    owningUid, exported);
4972        }
4973
4974        public Object getAMSLock() {
4975            return ActivityManagerService.this;
4976        }
4977    }
4978
4979    /**
4980     * This can be called with or without the global lock held.
4981     */
4982    int checkComponentPermission(String permission, int pid, int uid,
4983            int owningUid, boolean exported) {
4984        // We might be performing an operation on behalf of an indirect binder
4985        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4986        // client identity accordingly before proceeding.
4987        Identity tlsIdentity = sCallerIdentity.get();
4988        if (tlsIdentity != null) {
4989            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4990                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4991            uid = tlsIdentity.uid;
4992            pid = tlsIdentity.pid;
4993        }
4994
4995        if (pid == MY_PID) {
4996            return PackageManager.PERMISSION_GRANTED;
4997        }
4998
4999        return ActivityManager.checkComponentPermission(permission, uid,
5000                owningUid, exported);
5001    }
5002
5003    /**
5004     * As the only public entry point for permissions checking, this method
5005     * can enforce the semantic that requesting a check on a null global
5006     * permission is automatically denied.  (Internally a null permission
5007     * string is used when calling {@link #checkComponentPermission} in cases
5008     * when only uid-based security is needed.)
5009     *
5010     * This can be called with or without the global lock held.
5011     */
5012    public int checkPermission(String permission, int pid, int uid) {
5013        if (permission == null) {
5014            return PackageManager.PERMISSION_DENIED;
5015        }
5016        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5017    }
5018
5019    /**
5020     * Binder IPC calls go through the public entry point.
5021     * This can be called with or without the global lock held.
5022     */
5023    int checkCallingPermission(String permission) {
5024        return checkPermission(permission,
5025                Binder.getCallingPid(),
5026                UserHandle.getAppId(Binder.getCallingUid()));
5027    }
5028
5029    /**
5030     * This can be called with or without the global lock held.
5031     */
5032    void enforceCallingPermission(String permission, String func) {
5033        if (checkCallingPermission(permission)
5034                == PackageManager.PERMISSION_GRANTED) {
5035            return;
5036        }
5037
5038        String msg = "Permission Denial: " + func + " from pid="
5039                + Binder.getCallingPid()
5040                + ", uid=" + Binder.getCallingUid()
5041                + " requires " + permission;
5042        Slog.w(TAG, msg);
5043        throw new SecurityException(msg);
5044    }
5045
5046    /**
5047     * Determine if UID is holding permissions required to access {@link Uri} in
5048     * the given {@link ProviderInfo}. Final permission checking is always done
5049     * in {@link ContentProvider}.
5050     */
5051    private final boolean checkHoldingPermissionsLocked(
5052            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5053        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5054                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5055
5056        if (pi.applicationInfo.uid == uid) {
5057            return true;
5058        } else if (!pi.exported) {
5059            return false;
5060        }
5061
5062        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5063        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5064        try {
5065            // check if target holds top-level <provider> permissions
5066            if (!readMet && pi.readPermission != null
5067                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5068                readMet = true;
5069            }
5070            if (!writeMet && pi.writePermission != null
5071                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5072                writeMet = true;
5073            }
5074
5075            // track if unprotected read/write is allowed; any denied
5076            // <path-permission> below removes this ability
5077            boolean allowDefaultRead = pi.readPermission == null;
5078            boolean allowDefaultWrite = pi.writePermission == null;
5079
5080            // check if target holds any <path-permission> that match uri
5081            final PathPermission[] pps = pi.pathPermissions;
5082            if (pps != null) {
5083                final String path = uri.getPath();
5084                int i = pps.length;
5085                while (i > 0 && (!readMet || !writeMet)) {
5086                    i--;
5087                    PathPermission pp = pps[i];
5088                    if (pp.match(path)) {
5089                        if (!readMet) {
5090                            final String pprperm = pp.getReadPermission();
5091                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5092                                    + pprperm + " for " + pp.getPath()
5093                                    + ": match=" + pp.match(path)
5094                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5095                            if (pprperm != null) {
5096                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5097                                    readMet = true;
5098                                } else {
5099                                    allowDefaultRead = false;
5100                                }
5101                            }
5102                        }
5103                        if (!writeMet) {
5104                            final String ppwperm = pp.getWritePermission();
5105                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5106                                    + ppwperm + " for " + pp.getPath()
5107                                    + ": match=" + pp.match(path)
5108                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5109                            if (ppwperm != null) {
5110                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5111                                    writeMet = true;
5112                                } else {
5113                                    allowDefaultWrite = false;
5114                                }
5115                            }
5116                        }
5117                    }
5118                }
5119            }
5120
5121            // grant unprotected <provider> read/write, if not blocked by
5122            // <path-permission> above
5123            if (allowDefaultRead) readMet = true;
5124            if (allowDefaultWrite) writeMet = true;
5125
5126        } catch (RemoteException e) {
5127            return false;
5128        }
5129
5130        return readMet && writeMet;
5131    }
5132
5133    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5134            int modeFlags) {
5135        // Root gets to do everything.
5136        if (uid == 0) {
5137            return true;
5138        }
5139        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5140        if (perms == null) return false;
5141        UriPermission perm = perms.get(uri);
5142        if (perm == null) return false;
5143        return (modeFlags&perm.modeFlags) == modeFlags;
5144    }
5145
5146    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5147        enforceNotIsolatedCaller("checkUriPermission");
5148
5149        // Another redirected-binder-call permissions check as in
5150        // {@link checkComponentPermission}.
5151        Identity tlsIdentity = sCallerIdentity.get();
5152        if (tlsIdentity != null) {
5153            uid = tlsIdentity.uid;
5154            pid = tlsIdentity.pid;
5155        }
5156
5157        // Our own process gets to do everything.
5158        if (pid == MY_PID) {
5159            return PackageManager.PERMISSION_GRANTED;
5160        }
5161        synchronized(this) {
5162            return checkUriPermissionLocked(uri, uid, modeFlags)
5163                    ? PackageManager.PERMISSION_GRANTED
5164                    : PackageManager.PERMISSION_DENIED;
5165        }
5166    }
5167
5168    /**
5169     * Check if the targetPkg can be granted permission to access uri by
5170     * the callingUid using the given modeFlags.  Throws a security exception
5171     * if callingUid is not allowed to do this.  Returns the uid of the target
5172     * if the URI permission grant should be performed; returns -1 if it is not
5173     * needed (for example targetPkg already has permission to access the URI).
5174     * If you already know the uid of the target, you can supply it in
5175     * lastTargetUid else set that to -1.
5176     */
5177    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5178            Uri uri, int modeFlags, int lastTargetUid) {
5179        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5180                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5181        if (modeFlags == 0) {
5182            return -1;
5183        }
5184
5185        if (targetPkg != null) {
5186            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5187                    "Checking grant " + targetPkg + " permission to " + uri);
5188        }
5189
5190        final IPackageManager pm = AppGlobals.getPackageManager();
5191
5192        // If this is not a content: uri, we can't do anything with it.
5193        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5194            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5195                    "Can't grant URI permission for non-content URI: " + uri);
5196            return -1;
5197        }
5198
5199        String name = uri.getAuthority();
5200        ProviderInfo pi = null;
5201        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5202                UserHandle.getUserId(callingUid));
5203        if (cpr != null) {
5204            pi = cpr.info;
5205        } else {
5206            try {
5207                pi = pm.resolveContentProvider(name,
5208                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5209                        UserHandle.getUserId(callingUid));
5210            } catch (RemoteException ex) {
5211            }
5212        }
5213        if (pi == null) {
5214            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5215            return -1;
5216        }
5217
5218        int targetUid = lastTargetUid;
5219        if (targetUid < 0 && targetPkg != null) {
5220            try {
5221                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5222                if (targetUid < 0) {
5223                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5224                            "Can't grant URI permission no uid for: " + targetPkg);
5225                    return -1;
5226                }
5227            } catch (RemoteException ex) {
5228                return -1;
5229            }
5230        }
5231
5232        if (targetUid >= 0) {
5233            // First...  does the target actually need this permission?
5234            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5235                // No need to grant the target this permission.
5236                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5237                        "Target " + targetPkg + " already has full permission to " + uri);
5238                return -1;
5239            }
5240        } else {
5241            // First...  there is no target package, so can anyone access it?
5242            boolean allowed = pi.exported;
5243            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5244                if (pi.readPermission != null) {
5245                    allowed = false;
5246                }
5247            }
5248            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5249                if (pi.writePermission != null) {
5250                    allowed = false;
5251                }
5252            }
5253            if (allowed) {
5254                return -1;
5255            }
5256        }
5257
5258        // Second...  is the provider allowing granting of URI permissions?
5259        if (!pi.grantUriPermissions) {
5260            throw new SecurityException("Provider " + pi.packageName
5261                    + "/" + pi.name
5262                    + " does not allow granting of Uri permissions (uri "
5263                    + uri + ")");
5264        }
5265        if (pi.uriPermissionPatterns != null) {
5266            final int N = pi.uriPermissionPatterns.length;
5267            boolean allowed = false;
5268            for (int i=0; i<N; i++) {
5269                if (pi.uriPermissionPatterns[i] != null
5270                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5271                    allowed = true;
5272                    break;
5273                }
5274            }
5275            if (!allowed) {
5276                throw new SecurityException("Provider " + pi.packageName
5277                        + "/" + pi.name
5278                        + " does not allow granting of permission to path of Uri "
5279                        + uri);
5280            }
5281        }
5282
5283        // Third...  does the caller itself have permission to access
5284        // this uri?
5285        if (callingUid != Process.myUid()) {
5286            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5287                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5288                    throw new SecurityException("Uid " + callingUid
5289                            + " does not have permission to uri " + uri);
5290                }
5291            }
5292        }
5293
5294        return targetUid;
5295    }
5296
5297    public int checkGrantUriPermission(int callingUid, String targetPkg,
5298            Uri uri, int modeFlags) {
5299        enforceNotIsolatedCaller("checkGrantUriPermission");
5300        synchronized(this) {
5301            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5302        }
5303    }
5304
5305    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5306            Uri uri, int modeFlags, UriPermissionOwner owner) {
5307        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5308                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5309        if (modeFlags == 0) {
5310            return;
5311        }
5312
5313        // So here we are: the caller has the assumed permission
5314        // to the uri, and the target doesn't.  Let's now give this to
5315        // the target.
5316
5317        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5318                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5319
5320        HashMap<Uri, UriPermission> targetUris
5321                = mGrantedUriPermissions.get(targetUid);
5322        if (targetUris == null) {
5323            targetUris = new HashMap<Uri, UriPermission>();
5324            mGrantedUriPermissions.put(targetUid, targetUris);
5325        }
5326
5327        UriPermission perm = targetUris.get(uri);
5328        if (perm == null) {
5329            perm = new UriPermission(targetUid, uri);
5330            targetUris.put(uri, perm);
5331        }
5332
5333        perm.modeFlags |= modeFlags;
5334        if (owner == null) {
5335            perm.globalModeFlags |= modeFlags;
5336        } else {
5337            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5338                 perm.readOwners.add(owner);
5339                 owner.addReadPermission(perm);
5340            }
5341            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5342                 perm.writeOwners.add(owner);
5343                 owner.addWritePermission(perm);
5344            }
5345        }
5346    }
5347
5348    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5349            int modeFlags, UriPermissionOwner owner) {
5350        if (targetPkg == null) {
5351            throw new NullPointerException("targetPkg");
5352        }
5353
5354        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5355        if (targetUid < 0) {
5356            return;
5357        }
5358
5359        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5360    }
5361
5362    static class NeededUriGrants extends ArrayList<Uri> {
5363        final String targetPkg;
5364        final int targetUid;
5365        final int flags;
5366
5367        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5368            targetPkg = _targetPkg;
5369            targetUid = _targetUid;
5370            flags = _flags;
5371        }
5372    }
5373
5374    /**
5375     * Like checkGrantUriPermissionLocked, but takes an Intent.
5376     */
5377    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5378            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5379        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5380                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5381                + " clip=" + (intent != null ? intent.getClipData() : null)
5382                + " from " + intent + "; flags=0x"
5383                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5384
5385        if (targetPkg == null) {
5386            throw new NullPointerException("targetPkg");
5387        }
5388
5389        if (intent == null) {
5390            return null;
5391        }
5392        Uri data = intent.getData();
5393        ClipData clip = intent.getClipData();
5394        if (data == null && clip == null) {
5395            return null;
5396        }
5397        if (data != null) {
5398            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5399                mode, needed != null ? needed.targetUid : -1);
5400            if (target > 0) {
5401                if (needed == null) {
5402                    needed = new NeededUriGrants(targetPkg, target, mode);
5403                }
5404                needed.add(data);
5405            }
5406        }
5407        if (clip != null) {
5408            for (int i=0; i<clip.getItemCount(); i++) {
5409                Uri uri = clip.getItemAt(i).getUri();
5410                if (uri != null) {
5411                    int target = -1;
5412                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5413                            mode, needed != null ? needed.targetUid : -1);
5414                    if (target > 0) {
5415                        if (needed == null) {
5416                            needed = new NeededUriGrants(targetPkg, target, mode);
5417                        }
5418                        needed.add(uri);
5419                    }
5420                } else {
5421                    Intent clipIntent = clip.getItemAt(i).getIntent();
5422                    if (clipIntent != null) {
5423                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5424                                callingUid, targetPkg, clipIntent, mode, needed);
5425                        if (newNeeded != null) {
5426                            needed = newNeeded;
5427                        }
5428                    }
5429                }
5430            }
5431        }
5432
5433        return needed;
5434    }
5435
5436    /**
5437     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5438     */
5439    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5440            UriPermissionOwner owner) {
5441        if (needed != null) {
5442            for (int i=0; i<needed.size(); i++) {
5443                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5444                        needed.get(i), needed.flags, owner);
5445            }
5446        }
5447    }
5448
5449    void grantUriPermissionFromIntentLocked(int callingUid,
5450            String targetPkg, Intent intent, UriPermissionOwner owner) {
5451        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5452                intent, intent != null ? intent.getFlags() : 0, null);
5453        if (needed == null) {
5454            return;
5455        }
5456
5457        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5458    }
5459
5460    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5461            Uri uri, int modeFlags) {
5462        enforceNotIsolatedCaller("grantUriPermission");
5463        synchronized(this) {
5464            final ProcessRecord r = getRecordForAppLocked(caller);
5465            if (r == null) {
5466                throw new SecurityException("Unable to find app for caller "
5467                        + caller
5468                        + " when granting permission to uri " + uri);
5469            }
5470            if (targetPkg == null) {
5471                throw new IllegalArgumentException("null target");
5472            }
5473            if (uri == null) {
5474                throw new IllegalArgumentException("null uri");
5475            }
5476
5477            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5478                    null);
5479        }
5480    }
5481
5482    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5483        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5484                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5485            HashMap<Uri, UriPermission> perms
5486                    = mGrantedUriPermissions.get(perm.uid);
5487            if (perms != null) {
5488                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5489                        "Removing " + perm.uid + " permission to " + perm.uri);
5490                perms.remove(perm.uri);
5491                if (perms.size() == 0) {
5492                    mGrantedUriPermissions.remove(perm.uid);
5493                }
5494            }
5495        }
5496    }
5497
5498    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5499            int modeFlags) {
5500        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5501                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5502        if (modeFlags == 0) {
5503            return;
5504        }
5505
5506        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5507                "Revoking all granted permissions to " + uri);
5508
5509        final IPackageManager pm = AppGlobals.getPackageManager();
5510
5511        final String authority = uri.getAuthority();
5512        ProviderInfo pi = null;
5513        int userId = UserHandle.getUserId(callingUid);
5514        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5515        if (cpr != null) {
5516            pi = cpr.info;
5517        } else {
5518            try {
5519                pi = pm.resolveContentProvider(authority,
5520                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5521            } catch (RemoteException ex) {
5522            }
5523        }
5524        if (pi == null) {
5525            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5526            return;
5527        }
5528
5529        // Does the caller have this permission on the URI?
5530        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5531            // Right now, if you are not the original owner of the permission,
5532            // you are not allowed to revoke it.
5533            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5534                throw new SecurityException("Uid " + callingUid
5535                        + " does not have permission to uri " + uri);
5536            //}
5537        }
5538
5539        // Go through all of the permissions and remove any that match.
5540        final List<String> SEGMENTS = uri.getPathSegments();
5541        if (SEGMENTS != null) {
5542            final int NS = SEGMENTS.size();
5543            int N = mGrantedUriPermissions.size();
5544            for (int i=0; i<N; i++) {
5545                HashMap<Uri, UriPermission> perms
5546                        = mGrantedUriPermissions.valueAt(i);
5547                Iterator<UriPermission> it = perms.values().iterator();
5548            toploop:
5549                while (it.hasNext()) {
5550                    UriPermission perm = it.next();
5551                    Uri targetUri = perm.uri;
5552                    if (!authority.equals(targetUri.getAuthority())) {
5553                        continue;
5554                    }
5555                    List<String> targetSegments = targetUri.getPathSegments();
5556                    if (targetSegments == null) {
5557                        continue;
5558                    }
5559                    if (targetSegments.size() < NS) {
5560                        continue;
5561                    }
5562                    for (int j=0; j<NS; j++) {
5563                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5564                            continue toploop;
5565                        }
5566                    }
5567                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5568                            "Revoking " + perm.uid + " permission to " + perm.uri);
5569                    perm.clearModes(modeFlags);
5570                    if (perm.modeFlags == 0) {
5571                        it.remove();
5572                    }
5573                }
5574                if (perms.size() == 0) {
5575                    mGrantedUriPermissions.remove(
5576                            mGrantedUriPermissions.keyAt(i));
5577                    N--;
5578                    i--;
5579                }
5580            }
5581        }
5582    }
5583
5584    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5585            int modeFlags) {
5586        enforceNotIsolatedCaller("revokeUriPermission");
5587        synchronized(this) {
5588            final ProcessRecord r = getRecordForAppLocked(caller);
5589            if (r == null) {
5590                throw new SecurityException("Unable to find app for caller "
5591                        + caller
5592                        + " when revoking permission to uri " + uri);
5593            }
5594            if (uri == null) {
5595                Slog.w(TAG, "revokeUriPermission: null uri");
5596                return;
5597            }
5598
5599            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5600                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5601            if (modeFlags == 0) {
5602                return;
5603            }
5604
5605            final IPackageManager pm = AppGlobals.getPackageManager();
5606
5607            final String authority = uri.getAuthority();
5608            ProviderInfo pi = null;
5609            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5610            if (cpr != null) {
5611                pi = cpr.info;
5612            } else {
5613                try {
5614                    pi = pm.resolveContentProvider(authority,
5615                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5616                } catch (RemoteException ex) {
5617                }
5618            }
5619            if (pi == null) {
5620                Slog.w(TAG, "No content provider found for permission revoke: "
5621                        + uri.toSafeString());
5622                return;
5623            }
5624
5625            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5626        }
5627    }
5628
5629    @Override
5630    public IBinder newUriPermissionOwner(String name) {
5631        enforceNotIsolatedCaller("newUriPermissionOwner");
5632        synchronized(this) {
5633            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5634            return owner.getExternalTokenLocked();
5635        }
5636    }
5637
5638    @Override
5639    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5640            Uri uri, int modeFlags) {
5641        synchronized(this) {
5642            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5643            if (owner == null) {
5644                throw new IllegalArgumentException("Unknown owner: " + token);
5645            }
5646            if (fromUid != Binder.getCallingUid()) {
5647                if (Binder.getCallingUid() != Process.myUid()) {
5648                    // Only system code can grant URI permissions on behalf
5649                    // of other users.
5650                    throw new SecurityException("nice try");
5651                }
5652            }
5653            if (targetPkg == null) {
5654                throw new IllegalArgumentException("null target");
5655            }
5656            if (uri == null) {
5657                throw new IllegalArgumentException("null uri");
5658            }
5659
5660            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5661        }
5662    }
5663
5664    @Override
5665    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5666        synchronized(this) {
5667            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5668            if (owner == null) {
5669                throw new IllegalArgumentException("Unknown owner: " + token);
5670            }
5671
5672            if (uri == null) {
5673                owner.removeUriPermissionsLocked(mode);
5674            } else {
5675                owner.removeUriPermissionLocked(uri, mode);
5676            }
5677        }
5678    }
5679
5680    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5681        synchronized (this) {
5682            ProcessRecord app =
5683                who != null ? getRecordForAppLocked(who) : null;
5684            if (app == null) return;
5685
5686            Message msg = Message.obtain();
5687            msg.what = WAIT_FOR_DEBUGGER_MSG;
5688            msg.obj = app;
5689            msg.arg1 = waiting ? 1 : 0;
5690            mHandler.sendMessage(msg);
5691        }
5692    }
5693
5694    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5695        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5696        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5697        outInfo.availMem = Process.getFreeMemory();
5698        outInfo.totalMem = Process.getTotalMemory();
5699        outInfo.threshold = homeAppMem;
5700        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5701        outInfo.hiddenAppThreshold = hiddenAppMem;
5702        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5703                ProcessList.SERVICE_ADJ);
5704        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5705                ProcessList.VISIBLE_APP_ADJ);
5706        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5707                ProcessList.FOREGROUND_APP_ADJ);
5708    }
5709
5710    // =========================================================
5711    // TASK MANAGEMENT
5712    // =========================================================
5713
5714    public List getTasks(int maxNum, int flags,
5715                         IThumbnailReceiver receiver) {
5716        ArrayList list = new ArrayList();
5717
5718        PendingThumbnailsRecord pending = null;
5719        IApplicationThread topThumbnail = null;
5720        ActivityRecord topRecord = null;
5721
5722        synchronized(this) {
5723            if (localLOGV) Slog.v(
5724                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5725                + ", receiver=" + receiver);
5726
5727            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5728                    != PackageManager.PERMISSION_GRANTED) {
5729                if (receiver != null) {
5730                    // If the caller wants to wait for pending thumbnails,
5731                    // it ain't gonna get them.
5732                    try {
5733                        receiver.finished();
5734                    } catch (RemoteException ex) {
5735                    }
5736                }
5737                String msg = "Permission Denial: getTasks() from pid="
5738                        + Binder.getCallingPid()
5739                        + ", uid=" + Binder.getCallingUid()
5740                        + " requires " + android.Manifest.permission.GET_TASKS;
5741                Slog.w(TAG, msg);
5742                throw new SecurityException(msg);
5743            }
5744
5745            int pos = mMainStack.mHistory.size()-1;
5746            ActivityRecord next =
5747                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5748            ActivityRecord top = null;
5749            TaskRecord curTask = null;
5750            int numActivities = 0;
5751            int numRunning = 0;
5752            while (pos >= 0 && maxNum > 0) {
5753                final ActivityRecord r = next;
5754                pos--;
5755                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5756
5757                // Initialize state for next task if needed.
5758                if (top == null ||
5759                        (top.state == ActivityState.INITIALIZING
5760                            && top.task == r.task)) {
5761                    top = r;
5762                    curTask = r.task;
5763                    numActivities = numRunning = 0;
5764                }
5765
5766                // Add 'r' into the current task.
5767                numActivities++;
5768                if (r.app != null && r.app.thread != null) {
5769                    numRunning++;
5770                }
5771
5772                if (localLOGV) Slog.v(
5773                    TAG, r.intent.getComponent().flattenToShortString()
5774                    + ": task=" + r.task);
5775
5776                // If the next one is a different task, generate a new
5777                // TaskInfo entry for what we have.
5778                if (next == null || next.task != curTask) {
5779                    ActivityManager.RunningTaskInfo ci
5780                            = new ActivityManager.RunningTaskInfo();
5781                    ci.id = curTask.taskId;
5782                    ci.baseActivity = r.intent.getComponent();
5783                    ci.topActivity = top.intent.getComponent();
5784                    if (top.thumbHolder != null) {
5785                        ci.description = top.thumbHolder.lastDescription;
5786                    }
5787                    ci.numActivities = numActivities;
5788                    ci.numRunning = numRunning;
5789                    //System.out.println(
5790                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5791                    if (ci.thumbnail == null && receiver != null) {
5792                        if (localLOGV) Slog.v(
5793                            TAG, "State=" + top.state + "Idle=" + top.idle
5794                            + " app=" + top.app
5795                            + " thr=" + (top.app != null ? top.app.thread : null));
5796                        if (top.state == ActivityState.RESUMED
5797                                || top.state == ActivityState.PAUSING) {
5798                            if (top.idle && top.app != null
5799                                && top.app.thread != null) {
5800                                topRecord = top;
5801                                topThumbnail = top.app.thread;
5802                            } else {
5803                                top.thumbnailNeeded = true;
5804                            }
5805                        }
5806                        if (pending == null) {
5807                            pending = new PendingThumbnailsRecord(receiver);
5808                        }
5809                        pending.pendingRecords.add(top);
5810                    }
5811                    list.add(ci);
5812                    maxNum--;
5813                    top = null;
5814                }
5815            }
5816
5817            if (pending != null) {
5818                mPendingThumbnails.add(pending);
5819            }
5820        }
5821
5822        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5823
5824        if (topThumbnail != null) {
5825            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5826            try {
5827                topThumbnail.requestThumbnail(topRecord.appToken);
5828            } catch (Exception e) {
5829                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5830                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5831            }
5832        }
5833
5834        if (pending == null && receiver != null) {
5835            // In this case all thumbnails were available and the client
5836            // is being asked to be told when the remaining ones come in...
5837            // which is unusually, since the top-most currently running
5838            // activity should never have a canned thumbnail!  Oh well.
5839            try {
5840                receiver.finished();
5841            } catch (RemoteException ex) {
5842            }
5843        }
5844
5845        return list;
5846    }
5847
5848    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5849            int flags, int userId) {
5850        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5851                false, true, "getRecentTasks", null);
5852
5853        synchronized (this) {
5854            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5855                    "getRecentTasks()");
5856            final boolean detailed = checkCallingPermission(
5857                    android.Manifest.permission.GET_DETAILED_TASKS)
5858                    == PackageManager.PERMISSION_GRANTED;
5859
5860            IPackageManager pm = AppGlobals.getPackageManager();
5861
5862            final int N = mRecentTasks.size();
5863            ArrayList<ActivityManager.RecentTaskInfo> res
5864                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5865                            maxNum < N ? maxNum : N);
5866            for (int i=0; i<N && maxNum > 0; i++) {
5867                TaskRecord tr = mRecentTasks.get(i);
5868                // Only add calling user's recent tasks
5869                if (tr.userId != userId) continue;
5870                // Return the entry if desired by the caller.  We always return
5871                // the first entry, because callers always expect this to be the
5872                // foreground app.  We may filter others if the caller has
5873                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5874                // we should exclude the entry.
5875
5876                if (i == 0
5877                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5878                        || (tr.intent == null)
5879                        || ((tr.intent.getFlags()
5880                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5881                    ActivityManager.RecentTaskInfo rti
5882                            = new ActivityManager.RecentTaskInfo();
5883                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5884                    rti.persistentId = tr.taskId;
5885                    rti.baseIntent = new Intent(
5886                            tr.intent != null ? tr.intent : tr.affinityIntent);
5887                    if (!detailed) {
5888                        rti.baseIntent.replaceExtras((Bundle)null);
5889                    }
5890                    rti.origActivity = tr.origActivity;
5891                    rti.description = tr.lastDescription;
5892
5893                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5894                        // Check whether this activity is currently available.
5895                        try {
5896                            if (rti.origActivity != null) {
5897                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5898                                        == null) {
5899                                    continue;
5900                                }
5901                            } else if (rti.baseIntent != null) {
5902                                if (pm.queryIntentActivities(rti.baseIntent,
5903                                        null, 0, userId) == null) {
5904                                    continue;
5905                                }
5906                            }
5907                        } catch (RemoteException e) {
5908                            // Will never happen.
5909                        }
5910                    }
5911
5912                    res.add(rti);
5913                    maxNum--;
5914                }
5915            }
5916            return res;
5917        }
5918    }
5919
5920    private TaskRecord taskForIdLocked(int id) {
5921        final int N = mRecentTasks.size();
5922        for (int i=0; i<N; i++) {
5923            TaskRecord tr = mRecentTasks.get(i);
5924            if (tr.taskId == id) {
5925                return tr;
5926            }
5927        }
5928        return null;
5929    }
5930
5931    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5932        synchronized (this) {
5933            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5934                    "getTaskThumbnails()");
5935            TaskRecord tr = taskForIdLocked(id);
5936            if (tr != null) {
5937                return mMainStack.getTaskThumbnailsLocked(tr);
5938            }
5939        }
5940        return null;
5941    }
5942
5943    public Bitmap getTaskTopThumbnail(int id) {
5944        synchronized (this) {
5945            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5946                    "getTaskTopThumbnail()");
5947            TaskRecord tr = taskForIdLocked(id);
5948            if (tr != null) {
5949                return mMainStack.getTaskTopThumbnailLocked(tr);
5950            }
5951        }
5952        return null;
5953    }
5954
5955    public boolean removeSubTask(int taskId, int subTaskIndex) {
5956        synchronized (this) {
5957            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5958                    "removeSubTask()");
5959            long ident = Binder.clearCallingIdentity();
5960            try {
5961                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5962                        true) != null;
5963            } finally {
5964                Binder.restoreCallingIdentity(ident);
5965            }
5966        }
5967    }
5968
5969    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5970        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5971        Intent baseIntent = new Intent(
5972                tr.intent != null ? tr.intent : tr.affinityIntent);
5973        ComponentName component = baseIntent.getComponent();
5974        if (component == null) {
5975            Slog.w(TAG, "Now component for base intent of task: " + tr);
5976            return;
5977        }
5978
5979        // Find any running services associated with this app.
5980        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5981
5982        if (killProcesses) {
5983            // Find any running processes associated with this app.
5984            final String pkg = component.getPackageName();
5985            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5986            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5987            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5988                for (int i=0; i<uids.size(); i++) {
5989                    ProcessRecord proc = uids.valueAt(i);
5990                    if (proc.userId != tr.userId) {
5991                        continue;
5992                    }
5993                    if (!proc.pkgList.contains(pkg)) {
5994                        continue;
5995                    }
5996                    procs.add(proc);
5997                }
5998            }
5999
6000            // Kill the running processes.
6001            for (int i=0; i<procs.size(); i++) {
6002                ProcessRecord pr = procs.get(i);
6003                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6004                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6005                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6006                            pr.processName, pr.setAdj, "remove task");
6007                    pr.killedBackground = true;
6008                    Process.killProcessQuiet(pr.pid);
6009                } else {
6010                    pr.waitingToKill = "remove task";
6011                }
6012            }
6013        }
6014    }
6015
6016    public boolean removeTask(int taskId, int flags) {
6017        synchronized (this) {
6018            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6019                    "removeTask()");
6020            long ident = Binder.clearCallingIdentity();
6021            try {
6022                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
6023                        false);
6024                if (r != null) {
6025                    mRecentTasks.remove(r.task);
6026                    cleanUpRemovedTaskLocked(r.task, flags);
6027                    return true;
6028                } else {
6029                    TaskRecord tr = null;
6030                    int i=0;
6031                    while (i < mRecentTasks.size()) {
6032                        TaskRecord t = mRecentTasks.get(i);
6033                        if (t.taskId == taskId) {
6034                            tr = t;
6035                            break;
6036                        }
6037                        i++;
6038                    }
6039                    if (tr != null) {
6040                        if (tr.numActivities <= 0) {
6041                            // Caller is just removing a recent task that is
6042                            // not actively running.  That is easy!
6043                            mRecentTasks.remove(i);
6044                            cleanUpRemovedTaskLocked(tr, flags);
6045                            return true;
6046                        } else {
6047                            Slog.w(TAG, "removeTask: task " + taskId
6048                                    + " does not have activities to remove, "
6049                                    + " but numActivities=" + tr.numActivities
6050                                    + ": " + tr);
6051                        }
6052                    }
6053                }
6054            } finally {
6055                Binder.restoreCallingIdentity(ident);
6056            }
6057        }
6058        return false;
6059    }
6060
6061    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6062        int j;
6063        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
6064        TaskRecord jt = startTask;
6065
6066        // First look backwards
6067        for (j=startIndex-1; j>=0; j--) {
6068            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6069            if (r.task != jt) {
6070                jt = r.task;
6071                if (affinity.equals(jt.affinity)) {
6072                    return j;
6073                }
6074            }
6075        }
6076
6077        // Now look forwards
6078        final int N = mMainStack.mHistory.size();
6079        jt = startTask;
6080        for (j=startIndex+1; j<N; j++) {
6081            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6082            if (r.task != jt) {
6083                if (affinity.equals(jt.affinity)) {
6084                    return j;
6085                }
6086                jt = r.task;
6087            }
6088        }
6089
6090        // Might it be at the top?
6091        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6092            return N-1;
6093        }
6094
6095        return -1;
6096    }
6097
6098    /**
6099     * TODO: Add mController hook
6100     */
6101    public void moveTaskToFront(int task, int flags, Bundle options) {
6102        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6103                "moveTaskToFront()");
6104
6105        synchronized(this) {
6106            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6107                    Binder.getCallingUid(), "Task to front")) {
6108                ActivityOptions.abort(options);
6109                return;
6110            }
6111            final long origId = Binder.clearCallingIdentity();
6112            try {
6113                TaskRecord tr = taskForIdLocked(task);
6114                if (tr != null) {
6115                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6116                        mMainStack.mUserLeaving = true;
6117                    }
6118                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6119                        // Caller wants the home activity moved with it.  To accomplish this,
6120                        // we'll just move the home task to the top first.
6121                        mMainStack.moveHomeToFrontLocked();
6122                    }
6123                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6124                    return;
6125                }
6126                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6127                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6128                    if (hr.task.taskId == task) {
6129                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6130                            mMainStack.mUserLeaving = true;
6131                        }
6132                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6133                            // Caller wants the home activity moved with it.  To accomplish this,
6134                            // we'll just move the home task to the top first.
6135                            mMainStack.moveHomeToFrontLocked();
6136                        }
6137                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6138                        return;
6139                    }
6140                }
6141            } finally {
6142                Binder.restoreCallingIdentity(origId);
6143            }
6144            ActivityOptions.abort(options);
6145        }
6146    }
6147
6148    public void moveTaskToBack(int task) {
6149        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6150                "moveTaskToBack()");
6151
6152        synchronized(this) {
6153            if (mMainStack.mResumedActivity != null
6154                    && mMainStack.mResumedActivity.task.taskId == task) {
6155                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6156                        Binder.getCallingUid(), "Task to back")) {
6157                    return;
6158                }
6159            }
6160            final long origId = Binder.clearCallingIdentity();
6161            mMainStack.moveTaskToBackLocked(task, null);
6162            Binder.restoreCallingIdentity(origId);
6163        }
6164    }
6165
6166    /**
6167     * Moves an activity, and all of the other activities within the same task, to the bottom
6168     * of the history stack.  The activity's order within the task is unchanged.
6169     *
6170     * @param token A reference to the activity we wish to move
6171     * @param nonRoot If false then this only works if the activity is the root
6172     *                of a task; if true it will work for any activity in a task.
6173     * @return Returns true if the move completed, false if not.
6174     */
6175    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6176        enforceNotIsolatedCaller("moveActivityTaskToBack");
6177        synchronized(this) {
6178            final long origId = Binder.clearCallingIdentity();
6179            int taskId = getTaskForActivityLocked(token, !nonRoot);
6180            if (taskId >= 0) {
6181                return mMainStack.moveTaskToBackLocked(taskId, null);
6182            }
6183            Binder.restoreCallingIdentity(origId);
6184        }
6185        return false;
6186    }
6187
6188    public void moveTaskBackwards(int task) {
6189        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6190                "moveTaskBackwards()");
6191
6192        synchronized(this) {
6193            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6194                    Binder.getCallingUid(), "Task backwards")) {
6195                return;
6196            }
6197            final long origId = Binder.clearCallingIdentity();
6198            moveTaskBackwardsLocked(task);
6199            Binder.restoreCallingIdentity(origId);
6200        }
6201    }
6202
6203    private final void moveTaskBackwardsLocked(int task) {
6204        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6205    }
6206
6207    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6208        synchronized(this) {
6209            return getTaskForActivityLocked(token, onlyRoot);
6210        }
6211    }
6212
6213    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6214        final int N = mMainStack.mHistory.size();
6215        TaskRecord lastTask = null;
6216        for (int i=0; i<N; i++) {
6217            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6218            if (r.appToken == token) {
6219                if (!onlyRoot || lastTask != r.task) {
6220                    return r.task.taskId;
6221                }
6222                return -1;
6223            }
6224            lastTask = r.task;
6225        }
6226
6227        return -1;
6228    }
6229
6230    // =========================================================
6231    // THUMBNAILS
6232    // =========================================================
6233
6234    public void reportThumbnail(IBinder token,
6235            Bitmap thumbnail, CharSequence description) {
6236        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6237        final long origId = Binder.clearCallingIdentity();
6238        sendPendingThumbnail(null, token, thumbnail, description, true);
6239        Binder.restoreCallingIdentity(origId);
6240    }
6241
6242    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6243            Bitmap thumbnail, CharSequence description, boolean always) {
6244        TaskRecord task = null;
6245        ArrayList receivers = null;
6246
6247        //System.out.println("Send pending thumbnail: " + r);
6248
6249        synchronized(this) {
6250            if (r == null) {
6251                r = mMainStack.isInStackLocked(token);
6252                if (r == null) {
6253                    return;
6254                }
6255            }
6256            if (thumbnail == null && r.thumbHolder != null) {
6257                thumbnail = r.thumbHolder.lastThumbnail;
6258                description = r.thumbHolder.lastDescription;
6259            }
6260            if (thumbnail == null && !always) {
6261                // If there is no thumbnail, and this entry is not actually
6262                // going away, then abort for now and pick up the next
6263                // thumbnail we get.
6264                return;
6265            }
6266            task = r.task;
6267
6268            int N = mPendingThumbnails.size();
6269            int i=0;
6270            while (i<N) {
6271                PendingThumbnailsRecord pr =
6272                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6273                //System.out.println("Looking in " + pr.pendingRecords);
6274                if (pr.pendingRecords.remove(r)) {
6275                    if (receivers == null) {
6276                        receivers = new ArrayList();
6277                    }
6278                    receivers.add(pr);
6279                    if (pr.pendingRecords.size() == 0) {
6280                        pr.finished = true;
6281                        mPendingThumbnails.remove(i);
6282                        N--;
6283                        continue;
6284                    }
6285                }
6286                i++;
6287            }
6288        }
6289
6290        if (receivers != null) {
6291            final int N = receivers.size();
6292            for (int i=0; i<N; i++) {
6293                try {
6294                    PendingThumbnailsRecord pr =
6295                        (PendingThumbnailsRecord)receivers.get(i);
6296                    pr.receiver.newThumbnail(
6297                        task != null ? task.taskId : -1, thumbnail, description);
6298                    if (pr.finished) {
6299                        pr.receiver.finished();
6300                    }
6301                } catch (Exception e) {
6302                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6303                }
6304            }
6305        }
6306    }
6307
6308    // =========================================================
6309    // CONTENT PROVIDERS
6310    // =========================================================
6311
6312    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6313        List<ProviderInfo> providers = null;
6314        try {
6315            providers = AppGlobals.getPackageManager().
6316                queryContentProviders(app.processName, app.uid,
6317                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6318        } catch (RemoteException ex) {
6319        }
6320        if (DEBUG_MU)
6321            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6322        int userId = app.userId;
6323        if (providers != null) {
6324            int N = providers.size();
6325            for (int i=0; i<N; i++) {
6326                ProviderInfo cpi =
6327                    (ProviderInfo)providers.get(i);
6328                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6329                        cpi.name, cpi.flags);
6330                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6331                    // This is a singleton provider, but a user besides the
6332                    // default user is asking to initialize a process it runs
6333                    // in...  well, no, it doesn't actually run in this process,
6334                    // it runs in the process of the default user.  Get rid of it.
6335                    providers.remove(i);
6336                    N--;
6337                    continue;
6338                }
6339
6340                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6341                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6342                if (cpr == null) {
6343                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6344                    mProviderMap.putProviderByClass(comp, cpr);
6345                }
6346                if (DEBUG_MU)
6347                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6348                app.pubProviders.put(cpi.name, cpr);
6349                app.addPackage(cpi.applicationInfo.packageName);
6350                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6351            }
6352        }
6353        return providers;
6354    }
6355
6356    /**
6357     * Check if {@link ProcessRecord} has a possible chance at accessing the
6358     * given {@link ProviderInfo}. Final permission checking is always done
6359     * in {@link ContentProvider}.
6360     */
6361    private final String checkContentProviderPermissionLocked(
6362            ProviderInfo cpi, ProcessRecord r) {
6363        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6364        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6365        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6366                cpi.applicationInfo.uid, cpi.exported)
6367                == PackageManager.PERMISSION_GRANTED) {
6368            return null;
6369        }
6370        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6371                cpi.applicationInfo.uid, cpi.exported)
6372                == PackageManager.PERMISSION_GRANTED) {
6373            return null;
6374        }
6375
6376        PathPermission[] pps = cpi.pathPermissions;
6377        if (pps != null) {
6378            int i = pps.length;
6379            while (i > 0) {
6380                i--;
6381                PathPermission pp = pps[i];
6382                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6383                        cpi.applicationInfo.uid, cpi.exported)
6384                        == PackageManager.PERMISSION_GRANTED) {
6385                    return null;
6386                }
6387                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6388                        cpi.applicationInfo.uid, cpi.exported)
6389                        == PackageManager.PERMISSION_GRANTED) {
6390                    return null;
6391                }
6392            }
6393        }
6394
6395        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6396        if (perms != null) {
6397            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6398                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6399                    return null;
6400                }
6401            }
6402        }
6403
6404        String msg;
6405        if (!cpi.exported) {
6406            msg = "Permission Denial: opening provider " + cpi.name
6407                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6408                    + ", uid=" + callingUid + ") that is not exported from uid "
6409                    + cpi.applicationInfo.uid;
6410        } else {
6411            msg = "Permission Denial: opening provider " + cpi.name
6412                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6413                    + ", uid=" + callingUid + ") requires "
6414                    + cpi.readPermission + " or " + cpi.writePermission;
6415        }
6416        Slog.w(TAG, msg);
6417        return msg;
6418    }
6419
6420    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6421            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6422        if (r != null) {
6423            for (int i=0; i<r.conProviders.size(); i++) {
6424                ContentProviderConnection conn = r.conProviders.get(i);
6425                if (conn.provider == cpr) {
6426                    if (DEBUG_PROVIDER) Slog.v(TAG,
6427                            "Adding provider requested by "
6428                            + r.processName + " from process "
6429                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6430                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6431                    if (stable) {
6432                        conn.stableCount++;
6433                        conn.numStableIncs++;
6434                    } else {
6435                        conn.unstableCount++;
6436                        conn.numUnstableIncs++;
6437                    }
6438                    return conn;
6439                }
6440            }
6441            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6442            if (stable) {
6443                conn.stableCount = 1;
6444                conn.numStableIncs = 1;
6445            } else {
6446                conn.unstableCount = 1;
6447                conn.numUnstableIncs = 1;
6448            }
6449            cpr.connections.add(conn);
6450            r.conProviders.add(conn);
6451            return conn;
6452        }
6453        cpr.addExternalProcessHandleLocked(externalProcessToken);
6454        return null;
6455    }
6456
6457    boolean decProviderCountLocked(ContentProviderConnection conn,
6458            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6459        if (conn != null) {
6460            cpr = conn.provider;
6461            if (DEBUG_PROVIDER) Slog.v(TAG,
6462                    "Removing provider requested by "
6463                    + conn.client.processName + " from process "
6464                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6465                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6466            if (stable) {
6467                conn.stableCount--;
6468            } else {
6469                conn.unstableCount--;
6470            }
6471            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6472                cpr.connections.remove(conn);
6473                conn.client.conProviders.remove(conn);
6474                return true;
6475            }
6476            return false;
6477        }
6478        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6479        return false;
6480    }
6481
6482    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6483            String name, IBinder token, boolean stable, int userId) {
6484        ContentProviderRecord cpr;
6485        ContentProviderConnection conn = null;
6486        ProviderInfo cpi = null;
6487
6488        synchronized(this) {
6489            ProcessRecord r = null;
6490            if (caller != null) {
6491                r = getRecordForAppLocked(caller);
6492                if (r == null) {
6493                    throw new SecurityException(
6494                            "Unable to find app for caller " + caller
6495                          + " (pid=" + Binder.getCallingPid()
6496                          + ") when getting content provider " + name);
6497                }
6498            }
6499
6500            // First check if this content provider has been published...
6501            cpr = mProviderMap.getProviderByName(name, userId);
6502            boolean providerRunning = cpr != null;
6503            if (providerRunning) {
6504                cpi = cpr.info;
6505                String msg;
6506                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6507                    throw new SecurityException(msg);
6508                }
6509
6510                if (r != null && cpr.canRunHere(r)) {
6511                    // This provider has been published or is in the process
6512                    // of being published...  but it is also allowed to run
6513                    // in the caller's process, so don't make a connection
6514                    // and just let the caller instantiate its own instance.
6515                    ContentProviderHolder holder = cpr.newHolder(null);
6516                    // don't give caller the provider object, it needs
6517                    // to make its own.
6518                    holder.provider = null;
6519                    return holder;
6520                }
6521
6522                final long origId = Binder.clearCallingIdentity();
6523
6524                // In this case the provider instance already exists, so we can
6525                // return it right away.
6526                conn = incProviderCountLocked(r, cpr, token, stable);
6527                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6528                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6529                        // If this is a perceptible app accessing the provider,
6530                        // make sure to count it as being accessed and thus
6531                        // back up on the LRU list.  This is good because
6532                        // content providers are often expensive to start.
6533                        updateLruProcessLocked(cpr.proc, false);
6534                    }
6535                }
6536
6537                if (cpr.proc != null) {
6538                    if (false) {
6539                        if (cpr.name.flattenToShortString().equals(
6540                                "com.android.providers.calendar/.CalendarProvider2")) {
6541                            Slog.v(TAG, "****************** KILLING "
6542                                + cpr.name.flattenToShortString());
6543                            Process.killProcess(cpr.proc.pid);
6544                        }
6545                    }
6546                    boolean success = updateOomAdjLocked(cpr.proc);
6547                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6548                    // NOTE: there is still a race here where a signal could be
6549                    // pending on the process even though we managed to update its
6550                    // adj level.  Not sure what to do about this, but at least
6551                    // the race is now smaller.
6552                    if (!success) {
6553                        // Uh oh...  it looks like the provider's process
6554                        // has been killed on us.  We need to wait for a new
6555                        // process to be started, and make sure its death
6556                        // doesn't kill our process.
6557                        Slog.i(TAG,
6558                                "Existing provider " + cpr.name.flattenToShortString()
6559                                + " is crashing; detaching " + r);
6560                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6561                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6562                        if (!lastRef) {
6563                            // This wasn't the last ref our process had on
6564                            // the provider...  we have now been killed, bail.
6565                            return null;
6566                        }
6567                        providerRunning = false;
6568                        conn = null;
6569                    }
6570                }
6571
6572                Binder.restoreCallingIdentity(origId);
6573            }
6574
6575            boolean singleton;
6576            if (!providerRunning) {
6577                try {
6578                    cpi = AppGlobals.getPackageManager().
6579                        resolveContentProvider(name,
6580                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6581                } catch (RemoteException ex) {
6582                }
6583                if (cpi == null) {
6584                    return null;
6585                }
6586                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6587                        cpi.name, cpi.flags);
6588                if (singleton) {
6589                    userId = 0;
6590                }
6591                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6592
6593                String msg;
6594                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6595                    throw new SecurityException(msg);
6596                }
6597
6598                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6599                        && !cpi.processName.equals("system")) {
6600                    // If this content provider does not run in the system
6601                    // process, and the system is not yet ready to run other
6602                    // processes, then fail fast instead of hanging.
6603                    throw new IllegalArgumentException(
6604                            "Attempt to launch content provider before system ready");
6605                }
6606
6607                // Make sure that the user who owns this provider is started.  If not,
6608                // we don't want to allow it to run.
6609                if (mStartedUsers.get(userId) == null) {
6610                    Slog.w(TAG, "Unable to launch app "
6611                            + cpi.applicationInfo.packageName + "/"
6612                            + cpi.applicationInfo.uid + " for provider "
6613                            + name + ": user " + userId + " is stopped");
6614                    return null;
6615                }
6616
6617                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6618                cpr = mProviderMap.getProviderByClass(comp, userId);
6619                final boolean firstClass = cpr == null;
6620                if (firstClass) {
6621                    try {
6622                        ApplicationInfo ai =
6623                            AppGlobals.getPackageManager().
6624                                getApplicationInfo(
6625                                        cpi.applicationInfo.packageName,
6626                                        STOCK_PM_FLAGS, userId);
6627                        if (ai == null) {
6628                            Slog.w(TAG, "No package info for content provider "
6629                                    + cpi.name);
6630                            return null;
6631                        }
6632                        ai = getAppInfoForUser(ai, userId);
6633                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6634                    } catch (RemoteException ex) {
6635                        // pm is in same process, this will never happen.
6636                    }
6637                }
6638
6639                if (r != null && cpr.canRunHere(r)) {
6640                    // If this is a multiprocess provider, then just return its
6641                    // info and allow the caller to instantiate it.  Only do
6642                    // this if the provider is the same user as the caller's
6643                    // process, or can run as root (so can be in any process).
6644                    return cpr.newHolder(null);
6645                }
6646
6647                if (DEBUG_PROVIDER) {
6648                    RuntimeException e = new RuntimeException("here");
6649                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6650                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6651                }
6652
6653                // This is single process, and our app is now connecting to it.
6654                // See if we are already in the process of launching this
6655                // provider.
6656                final int N = mLaunchingProviders.size();
6657                int i;
6658                for (i=0; i<N; i++) {
6659                    if (mLaunchingProviders.get(i) == cpr) {
6660                        break;
6661                    }
6662                }
6663
6664                // If the provider is not already being launched, then get it
6665                // started.
6666                if (i >= N) {
6667                    final long origId = Binder.clearCallingIdentity();
6668
6669                    try {
6670                        // Content provider is now in use, its package can't be stopped.
6671                        try {
6672                            AppGlobals.getPackageManager().setPackageStoppedState(
6673                                    cpr.appInfo.packageName, false, userId);
6674                        } catch (RemoteException e) {
6675                        } catch (IllegalArgumentException e) {
6676                            Slog.w(TAG, "Failed trying to unstop package "
6677                                    + cpr.appInfo.packageName + ": " + e);
6678                        }
6679
6680                        ProcessRecord proc = startProcessLocked(cpi.processName,
6681                                cpr.appInfo, false, 0, "content provider",
6682                                new ComponentName(cpi.applicationInfo.packageName,
6683                                        cpi.name), false, false);
6684                        if (proc == null) {
6685                            Slog.w(TAG, "Unable to launch app "
6686                                    + cpi.applicationInfo.packageName + "/"
6687                                    + cpi.applicationInfo.uid + " for provider "
6688                                    + name + ": process is bad");
6689                            return null;
6690                        }
6691                        cpr.launchingApp = proc;
6692                        mLaunchingProviders.add(cpr);
6693                    } finally {
6694                        Binder.restoreCallingIdentity(origId);
6695                    }
6696                }
6697
6698                // Make sure the provider is published (the same provider class
6699                // may be published under multiple names).
6700                if (firstClass) {
6701                    mProviderMap.putProviderByClass(comp, cpr);
6702                }
6703
6704                mProviderMap.putProviderByName(name, cpr);
6705                conn = incProviderCountLocked(r, cpr, token, stable);
6706                if (conn != null) {
6707                    conn.waiting = true;
6708                }
6709            }
6710        }
6711
6712        // Wait for the provider to be published...
6713        synchronized (cpr) {
6714            while (cpr.provider == null) {
6715                if (cpr.launchingApp == null) {
6716                    Slog.w(TAG, "Unable to launch app "
6717                            + cpi.applicationInfo.packageName + "/"
6718                            + cpi.applicationInfo.uid + " for provider "
6719                            + name + ": launching app became null");
6720                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6721                            UserHandle.getUserId(cpi.applicationInfo.uid),
6722                            cpi.applicationInfo.packageName,
6723                            cpi.applicationInfo.uid, name);
6724                    return null;
6725                }
6726                try {
6727                    if (DEBUG_MU) {
6728                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6729                                + cpr.launchingApp);
6730                    }
6731                    if (conn != null) {
6732                        conn.waiting = true;
6733                    }
6734                    cpr.wait();
6735                } catch (InterruptedException ex) {
6736                } finally {
6737                    if (conn != null) {
6738                        conn.waiting = false;
6739                    }
6740                }
6741            }
6742        }
6743        return cpr != null ? cpr.newHolder(conn) : null;
6744    }
6745
6746    public final ContentProviderHolder getContentProvider(
6747            IApplicationThread caller, String name, int userId, boolean stable) {
6748        enforceNotIsolatedCaller("getContentProvider");
6749        if (caller == null) {
6750            String msg = "null IApplicationThread when getting content provider "
6751                    + name;
6752            Slog.w(TAG, msg);
6753            throw new SecurityException(msg);
6754        }
6755
6756        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6757                false, true, "getContentProvider", null);
6758        return getContentProviderImpl(caller, name, null, stable, userId);
6759    }
6760
6761    public ContentProviderHolder getContentProviderExternal(
6762            String name, int userId, IBinder token) {
6763        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6764            "Do not have permission in call getContentProviderExternal()");
6765        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6766                false, true, "getContentProvider", null);
6767        return getContentProviderExternalUnchecked(name, token, userId);
6768    }
6769
6770    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6771            IBinder token, int userId) {
6772        return getContentProviderImpl(null, name, token, true, userId);
6773    }
6774
6775    /**
6776     * Drop a content provider from a ProcessRecord's bookkeeping
6777     */
6778    public void removeContentProvider(IBinder connection, boolean stable) {
6779        enforceNotIsolatedCaller("removeContentProvider");
6780        synchronized (this) {
6781            ContentProviderConnection conn;
6782            try {
6783                conn = (ContentProviderConnection)connection;
6784            } catch (ClassCastException e) {
6785                String msg ="removeContentProvider: " + connection
6786                        + " not a ContentProviderConnection";
6787                Slog.w(TAG, msg);
6788                throw new IllegalArgumentException(msg);
6789            }
6790            if (conn == null) {
6791                throw new NullPointerException("connection is null");
6792            }
6793            if (decProviderCountLocked(conn, null, null, stable)) {
6794                updateOomAdjLocked();
6795            }
6796        }
6797    }
6798
6799    public void removeContentProviderExternal(String name, IBinder token) {
6800        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6801            "Do not have permission in call removeContentProviderExternal()");
6802        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6803    }
6804
6805    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6806        synchronized (this) {
6807            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6808            if(cpr == null) {
6809                //remove from mProvidersByClass
6810                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6811                return;
6812            }
6813
6814            //update content provider record entry info
6815            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6816            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6817            if (localCpr.hasExternalProcessHandles()) {
6818                if (localCpr.removeExternalProcessHandleLocked(token)) {
6819                    updateOomAdjLocked();
6820                } else {
6821                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6822                            + " with no external reference for token: "
6823                            + token + ".");
6824                }
6825            } else {
6826                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6827                        + " with no external references.");
6828            }
6829        }
6830    }
6831
6832    public final void publishContentProviders(IApplicationThread caller,
6833            List<ContentProviderHolder> providers) {
6834        if (providers == null) {
6835            return;
6836        }
6837
6838        enforceNotIsolatedCaller("publishContentProviders");
6839        synchronized (this) {
6840            final ProcessRecord r = getRecordForAppLocked(caller);
6841            if (DEBUG_MU)
6842                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6843            if (r == null) {
6844                throw new SecurityException(
6845                        "Unable to find app for caller " + caller
6846                      + " (pid=" + Binder.getCallingPid()
6847                      + ") when publishing content providers");
6848            }
6849
6850            final long origId = Binder.clearCallingIdentity();
6851
6852            final int N = providers.size();
6853            for (int i=0; i<N; i++) {
6854                ContentProviderHolder src = providers.get(i);
6855                if (src == null || src.info == null || src.provider == null) {
6856                    continue;
6857                }
6858                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6859                if (DEBUG_MU)
6860                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6861                if (dst != null) {
6862                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6863                    mProviderMap.putProviderByClass(comp, dst);
6864                    String names[] = dst.info.authority.split(";");
6865                    for (int j = 0; j < names.length; j++) {
6866                        mProviderMap.putProviderByName(names[j], dst);
6867                    }
6868
6869                    int NL = mLaunchingProviders.size();
6870                    int j;
6871                    for (j=0; j<NL; j++) {
6872                        if (mLaunchingProviders.get(j) == dst) {
6873                            mLaunchingProviders.remove(j);
6874                            j--;
6875                            NL--;
6876                        }
6877                    }
6878                    synchronized (dst) {
6879                        dst.provider = src.provider;
6880                        dst.proc = r;
6881                        dst.notifyAll();
6882                    }
6883                    updateOomAdjLocked(r);
6884                }
6885            }
6886
6887            Binder.restoreCallingIdentity(origId);
6888        }
6889    }
6890
6891    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6892        ContentProviderConnection conn;
6893        try {
6894            conn = (ContentProviderConnection)connection;
6895        } catch (ClassCastException e) {
6896            String msg ="refContentProvider: " + connection
6897                    + " not a ContentProviderConnection";
6898            Slog.w(TAG, msg);
6899            throw new IllegalArgumentException(msg);
6900        }
6901        if (conn == null) {
6902            throw new NullPointerException("connection is null");
6903        }
6904
6905        synchronized (this) {
6906            if (stable > 0) {
6907                conn.numStableIncs += stable;
6908            }
6909            stable = conn.stableCount + stable;
6910            if (stable < 0) {
6911                throw new IllegalStateException("stableCount < 0: " + stable);
6912            }
6913
6914            if (unstable > 0) {
6915                conn.numUnstableIncs += unstable;
6916            }
6917            unstable = conn.unstableCount + unstable;
6918            if (unstable < 0) {
6919                throw new IllegalStateException("unstableCount < 0: " + unstable);
6920            }
6921
6922            if ((stable+unstable) <= 0) {
6923                throw new IllegalStateException("ref counts can't go to zero here: stable="
6924                        + stable + " unstable=" + unstable);
6925            }
6926            conn.stableCount = stable;
6927            conn.unstableCount = unstable;
6928            return !conn.dead;
6929        }
6930    }
6931
6932    public void unstableProviderDied(IBinder connection) {
6933        ContentProviderConnection conn;
6934        try {
6935            conn = (ContentProviderConnection)connection;
6936        } catch (ClassCastException e) {
6937            String msg ="refContentProvider: " + connection
6938                    + " not a ContentProviderConnection";
6939            Slog.w(TAG, msg);
6940            throw new IllegalArgumentException(msg);
6941        }
6942        if (conn == null) {
6943            throw new NullPointerException("connection is null");
6944        }
6945
6946        // Safely retrieve the content provider associated with the connection.
6947        IContentProvider provider;
6948        synchronized (this) {
6949            provider = conn.provider.provider;
6950        }
6951
6952        if (provider == null) {
6953            // Um, yeah, we're way ahead of you.
6954            return;
6955        }
6956
6957        // Make sure the caller is being honest with us.
6958        if (provider.asBinder().pingBinder()) {
6959            // Er, no, still looks good to us.
6960            synchronized (this) {
6961                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6962                        + " says " + conn + " died, but we don't agree");
6963                return;
6964            }
6965        }
6966
6967        // Well look at that!  It's dead!
6968        synchronized (this) {
6969            if (conn.provider.provider != provider) {
6970                // But something changed...  good enough.
6971                return;
6972            }
6973
6974            ProcessRecord proc = conn.provider.proc;
6975            if (proc == null || proc.thread == null) {
6976                // Seems like the process is already cleaned up.
6977                return;
6978            }
6979
6980            // As far as we're concerned, this is just like receiving a
6981            // death notification...  just a bit prematurely.
6982            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6983                    + ") early provider death");
6984            final long ident = Binder.clearCallingIdentity();
6985            try {
6986                appDiedLocked(proc, proc.pid, proc.thread);
6987            } finally {
6988                Binder.restoreCallingIdentity(ident);
6989            }
6990        }
6991    }
6992
6993    public static final void installSystemProviders() {
6994        List<ProviderInfo> providers;
6995        synchronized (mSelf) {
6996            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6997            providers = mSelf.generateApplicationProvidersLocked(app);
6998            if (providers != null) {
6999                for (int i=providers.size()-1; i>=0; i--) {
7000                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7001                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7002                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7003                                + ": not system .apk");
7004                        providers.remove(i);
7005                    }
7006                }
7007            }
7008        }
7009        if (providers != null) {
7010            mSystemThread.installSystemProviders(providers);
7011        }
7012
7013        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
7014
7015        mSelf.mUsageStatsService.monitorPackages();
7016    }
7017
7018    /**
7019     * Allows app to retrieve the MIME type of a URI without having permission
7020     * to access its content provider.
7021     *
7022     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7023     *
7024     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7025     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7026     */
7027    public String getProviderMimeType(Uri uri, int userId) {
7028        enforceNotIsolatedCaller("getProviderMimeType");
7029        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7030                userId, false, true, "getProviderMimeType", null);
7031        final String name = uri.getAuthority();
7032        final long ident = Binder.clearCallingIdentity();
7033        ContentProviderHolder holder = null;
7034
7035        try {
7036            holder = getContentProviderExternalUnchecked(name, null, userId);
7037            if (holder != null) {
7038                return holder.provider.getType(uri);
7039            }
7040        } catch (RemoteException e) {
7041            Log.w(TAG, "Content provider dead retrieving " + uri, e);
7042            return null;
7043        } finally {
7044            if (holder != null) {
7045                removeContentProviderExternalUnchecked(name, null, userId);
7046            }
7047            Binder.restoreCallingIdentity(ident);
7048        }
7049
7050        return null;
7051    }
7052
7053    // =========================================================
7054    // GLOBAL MANAGEMENT
7055    // =========================================================
7056
7057    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7058            ApplicationInfo info, String customProcess, boolean isolated) {
7059        String proc = customProcess != null ? customProcess : info.processName;
7060        BatteryStatsImpl.Uid.Proc ps = null;
7061        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7062        int uid = info.uid;
7063        if (isolated) {
7064            int userId = UserHandle.getUserId(uid);
7065            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7066            uid = 0;
7067            while (true) {
7068                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7069                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7070                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7071                }
7072                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
7073                mNextIsolatedProcessUid++;
7074                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7075                    // No process for this uid, use it.
7076                    break;
7077                }
7078                stepsLeft--;
7079                if (stepsLeft <= 0) {
7080                    return null;
7081                }
7082            }
7083        }
7084        synchronized (stats) {
7085            ps = stats.getProcessStatsLocked(info.uid, proc);
7086        }
7087        return new ProcessRecord(ps, thread, info, proc, uid);
7088    }
7089
7090    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7091        ProcessRecord app;
7092        if (!isolated) {
7093            app = getProcessRecordLocked(info.processName, info.uid);
7094        } else {
7095            app = null;
7096        }
7097
7098        if (app == null) {
7099            app = newProcessRecordLocked(null, info, null, isolated);
7100            mProcessNames.put(info.processName, app.uid, app);
7101            if (isolated) {
7102                mIsolatedProcesses.put(app.uid, app);
7103            }
7104            updateLruProcessLocked(app, true);
7105        }
7106
7107        // This package really, really can not be stopped.
7108        try {
7109            AppGlobals.getPackageManager().setPackageStoppedState(
7110                    info.packageName, false, UserHandle.getUserId(app.uid));
7111        } catch (RemoteException e) {
7112        } catch (IllegalArgumentException e) {
7113            Slog.w(TAG, "Failed trying to unstop package "
7114                    + info.packageName + ": " + e);
7115        }
7116
7117        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7118                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7119            app.persistent = true;
7120            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7121        }
7122        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7123            mPersistentStartingProcesses.add(app);
7124            startProcessLocked(app, "added application", app.processName);
7125        }
7126
7127        return app;
7128    }
7129
7130    public void unhandledBack() {
7131        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7132                "unhandledBack()");
7133
7134        synchronized(this) {
7135            int count = mMainStack.mHistory.size();
7136            if (DEBUG_SWITCH) Slog.d(
7137                TAG, "Performing unhandledBack(): stack size = " + count);
7138            if (count > 1) {
7139                final long origId = Binder.clearCallingIdentity();
7140                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7141                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7142                Binder.restoreCallingIdentity(origId);
7143            }
7144        }
7145    }
7146
7147    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7148        enforceNotIsolatedCaller("openContentUri");
7149        final int userId = UserHandle.getCallingUserId();
7150        String name = uri.getAuthority();
7151        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7152        ParcelFileDescriptor pfd = null;
7153        if (cph != null) {
7154            // We record the binder invoker's uid in thread-local storage before
7155            // going to the content provider to open the file.  Later, in the code
7156            // that handles all permissions checks, we look for this uid and use
7157            // that rather than the Activity Manager's own uid.  The effect is that
7158            // we do the check against the caller's permissions even though it looks
7159            // to the content provider like the Activity Manager itself is making
7160            // the request.
7161            sCallerIdentity.set(new Identity(
7162                    Binder.getCallingPid(), Binder.getCallingUid()));
7163            try {
7164                pfd = cph.provider.openFile(null, uri, "r");
7165            } catch (FileNotFoundException e) {
7166                // do nothing; pfd will be returned null
7167            } finally {
7168                // Ensure that whatever happens, we clean up the identity state
7169                sCallerIdentity.remove();
7170            }
7171
7172            // We've got the fd now, so we're done with the provider.
7173            removeContentProviderExternalUnchecked(name, null, userId);
7174        } else {
7175            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7176        }
7177        return pfd;
7178    }
7179
7180    // Actually is sleeping or shutting down or whatever else in the future
7181    // is an inactive state.
7182    public boolean isSleeping() {
7183        return mSleeping || mShuttingDown;
7184    }
7185
7186    public void goingToSleep() {
7187        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7188                != PackageManager.PERMISSION_GRANTED) {
7189            throw new SecurityException("Requires permission "
7190                    + android.Manifest.permission.DEVICE_POWER);
7191        }
7192
7193        synchronized(this) {
7194            mWentToSleep = true;
7195            updateEventDispatchingLocked();
7196
7197            if (!mSleeping) {
7198                mSleeping = true;
7199                mMainStack.stopIfSleepingLocked();
7200
7201                // Initialize the wake times of all processes.
7202                checkExcessivePowerUsageLocked(false);
7203                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7204                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7205                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7206            }
7207        }
7208    }
7209
7210    public boolean shutdown(int timeout) {
7211        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7212                != PackageManager.PERMISSION_GRANTED) {
7213            throw new SecurityException("Requires permission "
7214                    + android.Manifest.permission.SHUTDOWN);
7215        }
7216
7217        boolean timedout = false;
7218
7219        synchronized(this) {
7220            mShuttingDown = true;
7221            updateEventDispatchingLocked();
7222
7223            if (mMainStack.mResumedActivity != null) {
7224                mMainStack.stopIfSleepingLocked();
7225                final long endTime = System.currentTimeMillis() + timeout;
7226                while (mMainStack.mResumedActivity != null
7227                        || mMainStack.mPausingActivity != null) {
7228                    long delay = endTime - System.currentTimeMillis();
7229                    if (delay <= 0) {
7230                        Slog.w(TAG, "Activity manager shutdown timed out");
7231                        timedout = true;
7232                        break;
7233                    }
7234                    try {
7235                        this.wait();
7236                    } catch (InterruptedException e) {
7237                    }
7238                }
7239            }
7240        }
7241
7242        mAppOpsService.shutdown();
7243        mUsageStatsService.shutdown();
7244        mBatteryStatsService.shutdown();
7245
7246        return timedout;
7247    }
7248
7249    public final void activitySlept(IBinder token) {
7250        if (localLOGV) Slog.v(
7251            TAG, "Activity slept: token=" + token);
7252
7253        ActivityRecord r = null;
7254
7255        final long origId = Binder.clearCallingIdentity();
7256
7257        synchronized (this) {
7258            r = mMainStack.isInStackLocked(token);
7259            if (r != null) {
7260                mMainStack.activitySleptLocked(r);
7261            }
7262        }
7263
7264        Binder.restoreCallingIdentity(origId);
7265    }
7266
7267    private void comeOutOfSleepIfNeededLocked() {
7268        if (!mWentToSleep && !mLockScreenShown) {
7269            if (mSleeping) {
7270                mSleeping = false;
7271                mMainStack.awakeFromSleepingLocked();
7272                mMainStack.resumeTopActivityLocked(null);
7273            }
7274        }
7275    }
7276
7277    public void wakingUp() {
7278        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7279                != PackageManager.PERMISSION_GRANTED) {
7280            throw new SecurityException("Requires permission "
7281                    + android.Manifest.permission.DEVICE_POWER);
7282        }
7283
7284        synchronized(this) {
7285            mWentToSleep = false;
7286            updateEventDispatchingLocked();
7287            comeOutOfSleepIfNeededLocked();
7288        }
7289    }
7290
7291    private void updateEventDispatchingLocked() {
7292        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7293    }
7294
7295    public void setLockScreenShown(boolean shown) {
7296        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7297                != PackageManager.PERMISSION_GRANTED) {
7298            throw new SecurityException("Requires permission "
7299                    + android.Manifest.permission.DEVICE_POWER);
7300        }
7301
7302        synchronized(this) {
7303            mLockScreenShown = shown;
7304            comeOutOfSleepIfNeededLocked();
7305        }
7306    }
7307
7308    public void stopAppSwitches() {
7309        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7310                != PackageManager.PERMISSION_GRANTED) {
7311            throw new SecurityException("Requires permission "
7312                    + android.Manifest.permission.STOP_APP_SWITCHES);
7313        }
7314
7315        synchronized(this) {
7316            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7317                    + APP_SWITCH_DELAY_TIME;
7318            mDidAppSwitch = false;
7319            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7320            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7321            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7322        }
7323    }
7324
7325    public void resumeAppSwitches() {
7326        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7327                != PackageManager.PERMISSION_GRANTED) {
7328            throw new SecurityException("Requires permission "
7329                    + android.Manifest.permission.STOP_APP_SWITCHES);
7330        }
7331
7332        synchronized(this) {
7333            // Note that we don't execute any pending app switches... we will
7334            // let those wait until either the timeout, or the next start
7335            // activity request.
7336            mAppSwitchesAllowedTime = 0;
7337        }
7338    }
7339
7340    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7341            String name) {
7342        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7343            return true;
7344        }
7345
7346        final int perm = checkComponentPermission(
7347                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7348                callingUid, -1, true);
7349        if (perm == PackageManager.PERMISSION_GRANTED) {
7350            return true;
7351        }
7352
7353        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7354        return false;
7355    }
7356
7357    public void setDebugApp(String packageName, boolean waitForDebugger,
7358            boolean persistent) {
7359        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7360                "setDebugApp()");
7361
7362        // Note that this is not really thread safe if there are multiple
7363        // callers into it at the same time, but that's not a situation we
7364        // care about.
7365        if (persistent) {
7366            final ContentResolver resolver = mContext.getContentResolver();
7367            Settings.Global.putString(
7368                resolver, Settings.Global.DEBUG_APP,
7369                packageName);
7370            Settings.Global.putInt(
7371                resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7372                waitForDebugger ? 1 : 0);
7373        }
7374
7375        synchronized (this) {
7376            if (!persistent) {
7377                mOrigDebugApp = mDebugApp;
7378                mOrigWaitForDebugger = mWaitForDebugger;
7379            }
7380            mDebugApp = packageName;
7381            mWaitForDebugger = waitForDebugger;
7382            mDebugTransient = !persistent;
7383            if (packageName != null) {
7384                final long origId = Binder.clearCallingIdentity();
7385                forceStopPackageLocked(packageName, -1, false, false, true, true,
7386                        UserHandle.USER_ALL);
7387                Binder.restoreCallingIdentity(origId);
7388            }
7389        }
7390    }
7391
7392    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7393        synchronized (this) {
7394            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7395            if (!isDebuggable) {
7396                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7397                    throw new SecurityException("Process not debuggable: " + app.packageName);
7398                }
7399            }
7400
7401            mOpenGlTraceApp = processName;
7402        }
7403    }
7404
7405    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7406            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7407        synchronized (this) {
7408            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7409            if (!isDebuggable) {
7410                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7411                    throw new SecurityException("Process not debuggable: " + app.packageName);
7412                }
7413            }
7414            mProfileApp = processName;
7415            mProfileFile = profileFile;
7416            if (mProfileFd != null) {
7417                try {
7418                    mProfileFd.close();
7419                } catch (IOException e) {
7420                }
7421                mProfileFd = null;
7422            }
7423            mProfileFd = profileFd;
7424            mProfileType = 0;
7425            mAutoStopProfiler = autoStopProfiler;
7426        }
7427    }
7428
7429    public void setAlwaysFinish(boolean enabled) {
7430        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7431                "setAlwaysFinish()");
7432
7433        Settings.Global.putInt(
7434                mContext.getContentResolver(),
7435                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7436
7437        synchronized (this) {
7438            mAlwaysFinishActivities = enabled;
7439        }
7440    }
7441
7442    public void setActivityController(IActivityController controller) {
7443        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7444                "setActivityController()");
7445        synchronized (this) {
7446            mController = controller;
7447            Watchdog.getInstance().setActivityController(controller);
7448        }
7449    }
7450
7451    public void setUserIsMonkey(boolean userIsMonkey) {
7452        synchronized (this) {
7453            synchronized (mPidsSelfLocked) {
7454                final int callingPid = Binder.getCallingPid();
7455                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
7456                if (precessRecord == null) {
7457                    throw new SecurityException("Unknown process: " + callingPid);
7458                }
7459                if (precessRecord.instrumentationUiAutomationConnection  == null) {
7460                    throw new SecurityException("Only an instrumentation process "
7461                            + "with a UiAutomation can call setUserIsMonkey");
7462                }
7463            }
7464            mUserIsMonkey = userIsMonkey;
7465        }
7466    }
7467
7468    public boolean isUserAMonkey() {
7469        synchronized (this) {
7470            // If there is a controller also implies the user is a monkey.
7471            return (mUserIsMonkey || mController != null);
7472        }
7473    }
7474
7475    public void requestBugReport() {
7476        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
7477        SystemProperties.set("ctl.start", "bugreport");
7478    }
7479
7480    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
7481        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
7482    }
7483
7484    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
7485        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
7486            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7487        }
7488        return KEY_DISPATCHING_TIMEOUT;
7489    }
7490
7491
7492    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
7493        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7494                != PackageManager.PERMISSION_GRANTED) {
7495            throw new SecurityException("Requires permission "
7496                    + android.Manifest.permission.FILTER_EVENTS);
7497        }
7498        ProcessRecord proc;
7499        long timeout;
7500        synchronized (this) {
7501            synchronized (mPidsSelfLocked) {
7502                proc = mPidsSelfLocked.get(pid);
7503            }
7504            timeout = getInputDispatchingTimeoutLocked(proc);
7505        }
7506
7507        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
7508            return -1;
7509        }
7510
7511        return timeout;
7512    }
7513
7514    /**
7515     * Handle input dispatching timeouts.
7516     * Returns whether input dispatching should be aborted or not.
7517     */
7518    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
7519            final ActivityRecord activity, final ActivityRecord parent,
7520            final boolean aboveSystem) {
7521        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7522                != PackageManager.PERMISSION_GRANTED) {
7523            throw new SecurityException("Requires permission "
7524                    + android.Manifest.permission.FILTER_EVENTS);
7525        }
7526
7527        if (proc != null) {
7528            synchronized (this) {
7529                if (proc.debugging) {
7530                    return false;
7531                }
7532
7533                if (mDidDexOpt) {
7534                    // Give more time since we were dexopting.
7535                    mDidDexOpt = false;
7536                    return false;
7537                }
7538
7539                if (proc.instrumentationClass != null) {
7540                    Bundle info = new Bundle();
7541                    info.putString("shortMsg", "keyDispatchingTimedOut");
7542                    info.putString("longMsg", "Timed out while dispatching key event");
7543                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7544                    return true;
7545                }
7546            }
7547            mHandler.post(new Runnable() {
7548                @Override
7549                public void run() {
7550                    appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
7551                }
7552            });
7553        }
7554
7555        return true;
7556    }
7557
7558    public Bundle getTopActivityExtras(int requestType) {
7559        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
7560                "getTopActivityExtras()");
7561        PendingActivityExtras pae;
7562        Bundle extras = new Bundle();
7563        synchronized (this) {
7564            ActivityRecord activity = mMainStack.mResumedActivity;
7565            if (activity == null) {
7566                Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
7567                return null;
7568            }
7569            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
7570            if (activity.app == null || activity.app.thread == null) {
7571                Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
7572                return extras;
7573            }
7574            if (activity.app.pid == Binder.getCallingPid()) {
7575                Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
7576                return extras;
7577            }
7578            pae = new PendingActivityExtras(activity);
7579            try {
7580                activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
7581                mPendingActivityExtras.add(pae);
7582                mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
7583            } catch (RemoteException e) {
7584                Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
7585                return extras;
7586            }
7587        }
7588        synchronized (pae) {
7589            while (!pae.haveResult) {
7590                try {
7591                    pae.wait();
7592                } catch (InterruptedException e) {
7593                }
7594            }
7595            if (pae.result != null) {
7596                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
7597            }
7598        }
7599        synchronized (this) {
7600            mPendingActivityExtras.remove(pae);
7601            mHandler.removeCallbacks(pae);
7602        }
7603        return extras;
7604    }
7605
7606    public void reportTopActivityExtras(IBinder token, Bundle extras) {
7607        PendingActivityExtras pae = (PendingActivityExtras)token;
7608        synchronized (pae) {
7609            pae.result = extras;
7610            pae.haveResult = true;
7611            pae.notifyAll();
7612        }
7613    }
7614
7615    public void registerProcessObserver(IProcessObserver observer) {
7616        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7617                "registerProcessObserver()");
7618        synchronized (this) {
7619            mProcessObservers.register(observer);
7620        }
7621    }
7622
7623    public void unregisterProcessObserver(IProcessObserver observer) {
7624        synchronized (this) {
7625            mProcessObservers.unregister(observer);
7626        }
7627    }
7628
7629    public void setImmersive(IBinder token, boolean immersive) {
7630        synchronized(this) {
7631            final ActivityRecord r = mMainStack.isInStackLocked(token);
7632            if (r == null) {
7633                throw new IllegalArgumentException();
7634            }
7635            r.immersive = immersive;
7636
7637            // update associated state if we're frontmost
7638            if (r == mFocusedActivity) {
7639                if (DEBUG_IMMERSIVE) {
7640                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
7641                }
7642                applyUpdateLockStateLocked(r);
7643            }
7644        }
7645    }
7646
7647    public boolean isImmersive(IBinder token) {
7648        synchronized (this) {
7649            ActivityRecord r = mMainStack.isInStackLocked(token);
7650            if (r == null) {
7651                throw new IllegalArgumentException();
7652            }
7653            return r.immersive;
7654        }
7655    }
7656
7657    public boolean isTopActivityImmersive() {
7658        enforceNotIsolatedCaller("startActivity");
7659        synchronized (this) {
7660            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7661            return (r != null) ? r.immersive : false;
7662        }
7663    }
7664
7665    public final void enterSafeMode() {
7666        synchronized(this) {
7667            // It only makes sense to do this before the system is ready
7668            // and started launching other packages.
7669            if (!mSystemReady) {
7670                try {
7671                    AppGlobals.getPackageManager().enterSafeMode();
7672                } catch (RemoteException e) {
7673                }
7674            }
7675        }
7676    }
7677
7678    public final void showSafeModeOverlay() {
7679        View v = LayoutInflater.from(mContext).inflate(
7680                com.android.internal.R.layout.safe_mode, null);
7681        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7682        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7683        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7684        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7685        lp.gravity = Gravity.BOTTOM | Gravity.START;
7686        lp.format = v.getBackground().getOpacity();
7687        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7688                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7689        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7690        ((WindowManager)mContext.getSystemService(
7691                Context.WINDOW_SERVICE)).addView(v, lp);
7692    }
7693
7694    public void noteWakeupAlarm(IIntentSender sender) {
7695        if (!(sender instanceof PendingIntentRecord)) {
7696            return;
7697        }
7698        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7699        synchronized (stats) {
7700            if (mBatteryStatsService.isOnBattery()) {
7701                mBatteryStatsService.enforceCallingPermission();
7702                PendingIntentRecord rec = (PendingIntentRecord)sender;
7703                int MY_UID = Binder.getCallingUid();
7704                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7705                BatteryStatsImpl.Uid.Pkg pkg =
7706                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7707                pkg.incWakeupsLocked();
7708            }
7709        }
7710    }
7711
7712    public boolean killPids(int[] pids, String pReason, boolean secure) {
7713        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7714            throw new SecurityException("killPids only available to the system");
7715        }
7716        String reason = (pReason == null) ? "Unknown" : pReason;
7717        // XXX Note: don't acquire main activity lock here, because the window
7718        // manager calls in with its locks held.
7719
7720        boolean killed = false;
7721        synchronized (mPidsSelfLocked) {
7722            int[] types = new int[pids.length];
7723            int worstType = 0;
7724            for (int i=0; i<pids.length; i++) {
7725                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7726                if (proc != null) {
7727                    int type = proc.setAdj;
7728                    types[i] = type;
7729                    if (type > worstType) {
7730                        worstType = type;
7731                    }
7732                }
7733            }
7734
7735            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7736            // then constrain it so we will kill all hidden procs.
7737            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7738                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7739                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7740            }
7741
7742            // If this is not a secure call, don't let it kill processes that
7743            // are important.
7744            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7745                worstType = ProcessList.SERVICE_ADJ;
7746            }
7747
7748            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7749            for (int i=0; i<pids.length; i++) {
7750                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7751                if (proc == null) {
7752                    continue;
7753                }
7754                int adj = proc.setAdj;
7755                if (adj >= worstType && !proc.killedBackground) {
7756                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7757                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7758                            proc.processName, adj, reason);
7759                    killed = true;
7760                    proc.killedBackground = true;
7761                    Process.killProcessQuiet(pids[i]);
7762                }
7763            }
7764        }
7765        return killed;
7766    }
7767
7768    @Override
7769    public void killUid(int uid, String reason) {
7770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7771            throw new SecurityException("killUid only available to the system");
7772        }
7773        synchronized (this) {
7774            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
7775                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
7776                    reason != null ? reason : "kill uid");
7777        }
7778    }
7779
7780    @Override
7781    public boolean killProcessesBelowForeground(String reason) {
7782        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7783            throw new SecurityException("killProcessesBelowForeground() only available to system");
7784        }
7785
7786        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7787    }
7788
7789    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7790        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7791            throw new SecurityException("killProcessesBelowAdj() only available to system");
7792        }
7793
7794        boolean killed = false;
7795        synchronized (mPidsSelfLocked) {
7796            final int size = mPidsSelfLocked.size();
7797            for (int i = 0; i < size; i++) {
7798                final int pid = mPidsSelfLocked.keyAt(i);
7799                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7800                if (proc == null) continue;
7801
7802                final int adj = proc.setAdj;
7803                if (adj > belowAdj && !proc.killedBackground) {
7804                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7805                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7806                            proc.pid, proc.processName, adj, reason);
7807                    killed = true;
7808                    proc.killedBackground = true;
7809                    Process.killProcessQuiet(pid);
7810                }
7811            }
7812        }
7813        return killed;
7814    }
7815
7816    @Override
7817    public void hang(final IBinder who, boolean allowRestart) {
7818        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
7819                != PackageManager.PERMISSION_GRANTED) {
7820            throw new SecurityException("Requires permission "
7821                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
7822        }
7823
7824        final IBinder.DeathRecipient death = new DeathRecipient() {
7825            @Override
7826            public void binderDied() {
7827                synchronized (this) {
7828                    notifyAll();
7829                }
7830            }
7831        };
7832
7833        try {
7834            who.linkToDeath(death, 0);
7835        } catch (RemoteException e) {
7836            Slog.w(TAG, "hang: given caller IBinder is already dead.");
7837            return;
7838        }
7839
7840        synchronized (this) {
7841            Watchdog.getInstance().setAllowRestart(allowRestart);
7842            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
7843            synchronized (death) {
7844                while (who.isBinderAlive()) {
7845                    try {
7846                        death.wait();
7847                    } catch (InterruptedException e) {
7848                    }
7849                }
7850            }
7851            Watchdog.getInstance().setAllowRestart(true);
7852        }
7853    }
7854
7855    public final void startRunning(String pkg, String cls, String action,
7856            String data) {
7857        synchronized(this) {
7858            if (mStartRunning) {
7859                return;
7860            }
7861            mStartRunning = true;
7862            mTopComponent = pkg != null && cls != null
7863                    ? new ComponentName(pkg, cls) : null;
7864            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7865            mTopData = data;
7866            if (!mSystemReady) {
7867                return;
7868            }
7869        }
7870
7871        systemReady(null);
7872    }
7873
7874    private void retrieveSettings() {
7875        final ContentResolver resolver = mContext.getContentResolver();
7876        String debugApp = Settings.Global.getString(
7877            resolver, Settings.Global.DEBUG_APP);
7878        boolean waitForDebugger = Settings.Global.getInt(
7879            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7880        boolean alwaysFinishActivities = Settings.Global.getInt(
7881            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7882
7883        Configuration configuration = new Configuration();
7884        Settings.System.getConfiguration(resolver, configuration);
7885
7886        synchronized (this) {
7887            mDebugApp = mOrigDebugApp = debugApp;
7888            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7889            mAlwaysFinishActivities = alwaysFinishActivities;
7890            // This happens before any activities are started, so we can
7891            // change mConfiguration in-place.
7892            updateConfigurationLocked(configuration, null, false, true);
7893            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7894        }
7895    }
7896
7897    public boolean testIsSystemReady() {
7898        // no need to synchronize(this) just to read & return the value
7899        return mSystemReady;
7900    }
7901
7902    private static File getCalledPreBootReceiversFile() {
7903        File dataDir = Environment.getDataDirectory();
7904        File systemDir = new File(dataDir, "system");
7905        File fname = new File(systemDir, "called_pre_boots.dat");
7906        return fname;
7907    }
7908
7909    static final int LAST_DONE_VERSION = 10000;
7910
7911    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7912        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7913        File file = getCalledPreBootReceiversFile();
7914        FileInputStream fis = null;
7915        try {
7916            fis = new FileInputStream(file);
7917            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7918            int fvers = dis.readInt();
7919            if (fvers == LAST_DONE_VERSION) {
7920                String vers = dis.readUTF();
7921                String codename = dis.readUTF();
7922                String build = dis.readUTF();
7923                if (android.os.Build.VERSION.RELEASE.equals(vers)
7924                        && android.os.Build.VERSION.CODENAME.equals(codename)
7925                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7926                    int num = dis.readInt();
7927                    while (num > 0) {
7928                        num--;
7929                        String pkg = dis.readUTF();
7930                        String cls = dis.readUTF();
7931                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7932                    }
7933                }
7934            }
7935        } catch (FileNotFoundException e) {
7936        } catch (IOException e) {
7937            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7938        } finally {
7939            if (fis != null) {
7940                try {
7941                    fis.close();
7942                } catch (IOException e) {
7943                }
7944            }
7945        }
7946        return lastDoneReceivers;
7947    }
7948
7949    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7950        File file = getCalledPreBootReceiversFile();
7951        FileOutputStream fos = null;
7952        DataOutputStream dos = null;
7953        try {
7954            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7955            fos = new FileOutputStream(file);
7956            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7957            dos.writeInt(LAST_DONE_VERSION);
7958            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7959            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7960            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7961            dos.writeInt(list.size());
7962            for (int i=0; i<list.size(); i++) {
7963                dos.writeUTF(list.get(i).getPackageName());
7964                dos.writeUTF(list.get(i).getClassName());
7965            }
7966        } catch (IOException e) {
7967            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7968            file.delete();
7969        } finally {
7970            FileUtils.sync(fos);
7971            if (dos != null) {
7972                try {
7973                    dos.close();
7974                } catch (IOException e) {
7975                    // TODO Auto-generated catch block
7976                    e.printStackTrace();
7977                }
7978            }
7979        }
7980    }
7981
7982    public void systemReady(final Runnable goingCallback) {
7983        synchronized(this) {
7984            if (mSystemReady) {
7985                if (goingCallback != null) goingCallback.run();
7986                return;
7987            }
7988
7989            // Check to see if there are any update receivers to run.
7990            if (!mDidUpdate) {
7991                if (mWaitingUpdate) {
7992                    return;
7993                }
7994                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7995                List<ResolveInfo> ris = null;
7996                try {
7997                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7998                            intent, null, 0, 0);
7999                } catch (RemoteException e) {
8000                }
8001                if (ris != null) {
8002                    for (int i=ris.size()-1; i>=0; i--) {
8003                        if ((ris.get(i).activityInfo.applicationInfo.flags
8004                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
8005                            ris.remove(i);
8006                        }
8007                    }
8008                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8009
8010                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
8011
8012                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
8013                    for (int i=0; i<ris.size(); i++) {
8014                        ActivityInfo ai = ris.get(i).activityInfo;
8015                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
8016                        if (lastDoneReceivers.contains(comp)) {
8017                            ris.remove(i);
8018                            i--;
8019                        }
8020                    }
8021
8022                    final int[] users = getUsersLocked();
8023                    for (int i=0; i<ris.size(); i++) {
8024                        ActivityInfo ai = ris.get(i).activityInfo;
8025                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
8026                        doneReceivers.add(comp);
8027                        intent.setComponent(comp);
8028                        for (int j=0; j<users.length; j++) {
8029                            IIntentReceiver finisher = null;
8030                            if (i == ris.size()-1 && j == users.length-1) {
8031                                finisher = new IIntentReceiver.Stub() {
8032                                    public void performReceive(Intent intent, int resultCode,
8033                                            String data, Bundle extras, boolean ordered,
8034                                            boolean sticky, int sendingUser) {
8035                                        // The raw IIntentReceiver interface is called
8036                                        // with the AM lock held, so redispatch to
8037                                        // execute our code without the lock.
8038                                        mHandler.post(new Runnable() {
8039                                            public void run() {
8040                                                synchronized (ActivityManagerService.this) {
8041                                                    mDidUpdate = true;
8042                                                }
8043                                                writeLastDonePreBootReceivers(doneReceivers);
8044                                                showBootMessage(mContext.getText(
8045                                                        R.string.android_upgrading_complete),
8046                                                        false);
8047                                                systemReady(goingCallback);
8048                                            }
8049                                        });
8050                                    }
8051                                };
8052                            }
8053                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
8054                                    + " for user " + users[j]);
8055                            broadcastIntentLocked(null, null, intent, null, finisher,
8056                                    0, null, null, null, AppOpsManager.OP_NONE,
8057                                    true, false, MY_PID, Process.SYSTEM_UID,
8058                                    users[j]);
8059                            if (finisher != null) {
8060                                mWaitingUpdate = true;
8061                            }
8062                        }
8063                    }
8064                }
8065                if (mWaitingUpdate) {
8066                    return;
8067                }
8068                mDidUpdate = true;
8069            }
8070
8071            mAppOpsService.systemReady();
8072            mSystemReady = true;
8073            if (!mStartRunning) {
8074                return;
8075            }
8076        }
8077
8078        ArrayList<ProcessRecord> procsToKill = null;
8079        synchronized(mPidsSelfLocked) {
8080            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8081                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8082                if (!isAllowedWhileBooting(proc.info)){
8083                    if (procsToKill == null) {
8084                        procsToKill = new ArrayList<ProcessRecord>();
8085                    }
8086                    procsToKill.add(proc);
8087                }
8088            }
8089        }
8090
8091        synchronized(this) {
8092            if (procsToKill != null) {
8093                for (int i=procsToKill.size()-1; i>=0; i--) {
8094                    ProcessRecord proc = procsToKill.get(i);
8095                    Slog.i(TAG, "Removing system update proc: " + proc);
8096                    removeProcessLocked(proc, true, false, "system update done");
8097                }
8098            }
8099
8100            // Now that we have cleaned up any update processes, we
8101            // are ready to start launching real processes and know that
8102            // we won't trample on them any more.
8103            mProcessesReady = true;
8104        }
8105
8106        Slog.i(TAG, "System now ready");
8107        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
8108            SystemClock.uptimeMillis());
8109
8110        synchronized(this) {
8111            // Make sure we have no pre-ready processes sitting around.
8112
8113            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8114                ResolveInfo ri = mContext.getPackageManager()
8115                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8116                                STOCK_PM_FLAGS);
8117                CharSequence errorMsg = null;
8118                if (ri != null) {
8119                    ActivityInfo ai = ri.activityInfo;
8120                    ApplicationInfo app = ai.applicationInfo;
8121                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8122                        mTopAction = Intent.ACTION_FACTORY_TEST;
8123                        mTopData = null;
8124                        mTopComponent = new ComponentName(app.packageName,
8125                                ai.name);
8126                    } else {
8127                        errorMsg = mContext.getResources().getText(
8128                                com.android.internal.R.string.factorytest_not_system);
8129                    }
8130                } else {
8131                    errorMsg = mContext.getResources().getText(
8132                            com.android.internal.R.string.factorytest_no_action);
8133                }
8134                if (errorMsg != null) {
8135                    mTopAction = null;
8136                    mTopData = null;
8137                    mTopComponent = null;
8138                    Message msg = Message.obtain();
8139                    msg.what = SHOW_FACTORY_ERROR_MSG;
8140                    msg.getData().putCharSequence("msg", errorMsg);
8141                    mHandler.sendMessage(msg);
8142                }
8143            }
8144        }
8145
8146        retrieveSettings();
8147
8148        if (goingCallback != null) goingCallback.run();
8149
8150        synchronized (this) {
8151            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8152                try {
8153                    List apps = AppGlobals.getPackageManager().
8154                        getPersistentApplications(STOCK_PM_FLAGS);
8155                    if (apps != null) {
8156                        int N = apps.size();
8157                        int i;
8158                        for (i=0; i<N; i++) {
8159                            ApplicationInfo info
8160                                = (ApplicationInfo)apps.get(i);
8161                            if (info != null &&
8162                                    !info.packageName.equals("android")) {
8163                                addAppLocked(info, false);
8164                            }
8165                        }
8166                    }
8167                } catch (RemoteException ex) {
8168                    // pm is in same process, this will never happen.
8169                }
8170            }
8171
8172            // Start up initial activity.
8173            mBooting = true;
8174
8175            try {
8176                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
8177                    Message msg = Message.obtain();
8178                    msg.what = SHOW_UID_ERROR_MSG;
8179                    mHandler.sendMessage(msg);
8180                }
8181            } catch (RemoteException e) {
8182            }
8183
8184            long ident = Binder.clearCallingIdentity();
8185            try {
8186                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
8187                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
8188                        | Intent.FLAG_RECEIVER_FOREGROUND);
8189                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
8190                broadcastIntentLocked(null, null, intent,
8191                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
8192                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
8193                intent = new Intent(Intent.ACTION_USER_STARTING);
8194                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
8195                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
8196                broadcastIntentLocked(null, null, intent,
8197                        null, new IIntentReceiver.Stub() {
8198                            @Override
8199                            public void performReceive(Intent intent, int resultCode, String data,
8200                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
8201                                    throws RemoteException {
8202                            }
8203                        }, 0, null, null,
8204                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
8205                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
8206            } finally {
8207                Binder.restoreCallingIdentity(ident);
8208            }
8209            mMainStack.resumeTopActivityLocked(null);
8210            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
8211        }
8212    }
8213
8214    private boolean makeAppCrashingLocked(ProcessRecord app,
8215            String shortMsg, String longMsg, String stackTrace) {
8216        app.crashing = true;
8217        app.crashingReport = generateProcessError(app,
8218                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
8219        startAppProblemLocked(app);
8220        app.stopFreezingAllLocked();
8221        return handleAppCrashLocked(app);
8222    }
8223
8224    private void makeAppNotRespondingLocked(ProcessRecord app,
8225            String activity, String shortMsg, String longMsg) {
8226        app.notResponding = true;
8227        app.notRespondingReport = generateProcessError(app,
8228                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8229                activity, shortMsg, longMsg, null);
8230        startAppProblemLocked(app);
8231        app.stopFreezingAllLocked();
8232    }
8233
8234    /**
8235     * Generate a process error record, suitable for attachment to a ProcessRecord.
8236     *
8237     * @param app The ProcessRecord in which the error occurred.
8238     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8239     *                      ActivityManager.AppErrorStateInfo
8240     * @param activity The activity associated with the crash, if known.
8241     * @param shortMsg Short message describing the crash.
8242     * @param longMsg Long message describing the crash.
8243     * @param stackTrace Full crash stack trace, may be null.
8244     *
8245     * @return Returns a fully-formed AppErrorStateInfo record.
8246     */
8247    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8248            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8249        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8250
8251        report.condition = condition;
8252        report.processName = app.processName;
8253        report.pid = app.pid;
8254        report.uid = app.info.uid;
8255        report.tag = activity;
8256        report.shortMsg = shortMsg;
8257        report.longMsg = longMsg;
8258        report.stackTrace = stackTrace;
8259
8260        return report;
8261    }
8262
8263    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
8264        synchronized (this) {
8265            app.crashing = false;
8266            app.crashingReport = null;
8267            app.notResponding = false;
8268            app.notRespondingReport = null;
8269            if (app.anrDialog == fromDialog) {
8270                app.anrDialog = null;
8271            }
8272            if (app.waitDialog == fromDialog) {
8273                app.waitDialog = null;
8274            }
8275            if (app.pid > 0 && app.pid != MY_PID) {
8276                handleAppCrashLocked(app);
8277                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
8278                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8279                        app.processName, app.setAdj, "user's request after error");
8280                Process.killProcessQuiet(app.pid);
8281            }
8282        }
8283    }
8284
8285    private boolean handleAppCrashLocked(ProcessRecord app) {
8286        if (mHeadless) {
8287            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8288            return false;
8289        }
8290        long now = SystemClock.uptimeMillis();
8291
8292        Long crashTime;
8293        if (!app.isolated) {
8294            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8295        } else {
8296            crashTime = null;
8297        }
8298        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8299            // This process loses!
8300            Slog.w(TAG, "Process " + app.info.processName
8301                    + " has crashed too many times: killing!");
8302            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8303                    app.userId, app.info.processName, app.uid);
8304            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8305                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8306                if (r.app == app) {
8307                    Slog.w(TAG, "  Force finishing activity "
8308                        + r.intent.getComponent().flattenToShortString());
8309                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8310                            null, "crashed", false);
8311                }
8312            }
8313            if (!app.persistent) {
8314                // We don't want to start this process again until the user
8315                // explicitly does so...  but for persistent process, we really
8316                // need to keep it running.  If a persistent process is actually
8317                // repeatedly crashing, then badness for everyone.
8318                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8319                        app.info.processName);
8320                if (!app.isolated) {
8321                    // XXX We don't have a way to mark isolated processes
8322                    // as bad, since they don't have a peristent identity.
8323                    mBadProcesses.put(app.info.processName, app.uid, now);
8324                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8325                }
8326                app.bad = true;
8327                app.removed = true;
8328                // Don't let services in this process be restarted and potentially
8329                // annoy the user repeatedly.  Unless it is persistent, since those
8330                // processes run critical code.
8331                removeProcessLocked(app, false, false, "crash");
8332                mMainStack.resumeTopActivityLocked(null);
8333                return false;
8334            }
8335            mMainStack.resumeTopActivityLocked(null);
8336        } else {
8337            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8338            if (r != null && r.app == app) {
8339                // If the top running activity is from this crashing
8340                // process, then terminate it to avoid getting in a loop.
8341                Slog.w(TAG, "  Force finishing activity "
8342                        + r.intent.getComponent().flattenToShortString());
8343                int index = mMainStack.indexOfActivityLocked(r);
8344                r.stack.finishActivityLocked(r, index,
8345                        Activity.RESULT_CANCELED, null, "crashed", false);
8346                // Also terminate any activities below it that aren't yet
8347                // stopped, to avoid a situation where one will get
8348                // re-start our crashing activity once it gets resumed again.
8349                index--;
8350                if (index >= 0) {
8351                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8352                    if (r.state == ActivityState.RESUMED
8353                            || r.state == ActivityState.PAUSING
8354                            || r.state == ActivityState.PAUSED) {
8355                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8356                            Slog.w(TAG, "  Force finishing activity "
8357                                    + r.intent.getComponent().flattenToShortString());
8358                            r.stack.finishActivityLocked(r, index,
8359                                    Activity.RESULT_CANCELED, null, "crashed", false);
8360                        }
8361                    }
8362                }
8363            }
8364        }
8365
8366        // Bump up the crash count of any services currently running in the proc.
8367        if (app.services.size() != 0) {
8368            // Any services running in the application need to be placed
8369            // back in the pending list.
8370            Iterator<ServiceRecord> it = app.services.iterator();
8371            while (it.hasNext()) {
8372                ServiceRecord sr = it.next();
8373                sr.crashCount++;
8374            }
8375        }
8376
8377        // If the crashing process is what we consider to be the "home process" and it has been
8378        // replaced by a third-party app, clear the package preferred activities from packages
8379        // with a home activity running in the process to prevent a repeatedly crashing app
8380        // from blocking the user to manually clear the list.
8381        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8382                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8383            Iterator it = mHomeProcess.activities.iterator();
8384            while (it.hasNext()) {
8385                ActivityRecord r = (ActivityRecord)it.next();
8386                if (r.isHomeActivity) {
8387                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8388                    try {
8389                        ActivityThread.getPackageManager()
8390                                .clearPackagePreferredActivities(r.packageName);
8391                    } catch (RemoteException c) {
8392                        // pm is in same process, this will never happen.
8393                    }
8394                }
8395            }
8396        }
8397
8398        if (!app.isolated) {
8399            // XXX Can't keep track of crash times for isolated processes,
8400            // because they don't have a perisistent identity.
8401            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8402        }
8403
8404        return true;
8405    }
8406
8407    void startAppProblemLocked(ProcessRecord app) {
8408        if (app.userId == mCurrentUserId) {
8409            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8410                    mContext, app.info.packageName, app.info.flags);
8411        } else {
8412            // If this app is not running under the current user, then we
8413            // can't give it a report button because that would require
8414            // launching the report UI under a different user.
8415            app.errorReportReceiver = null;
8416        }
8417        skipCurrentReceiverLocked(app);
8418    }
8419
8420    void skipCurrentReceiverLocked(ProcessRecord app) {
8421        for (BroadcastQueue queue : mBroadcastQueues) {
8422            queue.skipCurrentReceiverLocked(app);
8423        }
8424    }
8425
8426    /**
8427     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8428     * The application process will exit immediately after this call returns.
8429     * @param app object of the crashing app, null for the system server
8430     * @param crashInfo describing the exception
8431     */
8432    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8433        ProcessRecord r = findAppProcess(app, "Crash");
8434        final String processName = app == null ? "system_server"
8435                : (r == null ? "unknown" : r.processName);
8436
8437        handleApplicationCrashInner("crash", r, processName, crashInfo);
8438    }
8439
8440    /* Native crash reporting uses this inner version because it needs to be somewhat
8441     * decoupled from the AM-managed cleanup lifecycle
8442     */
8443    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
8444            ApplicationErrorReport.CrashInfo crashInfo) {
8445        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8446                UserHandle.getUserId(Binder.getCallingUid()), processName,
8447                r == null ? -1 : r.info.flags,
8448                crashInfo.exceptionClassName,
8449                crashInfo.exceptionMessage,
8450                crashInfo.throwFileName,
8451                crashInfo.throwLineNumber);
8452
8453        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
8454
8455        crashApplication(r, crashInfo);
8456    }
8457
8458    public void handleApplicationStrictModeViolation(
8459            IBinder app,
8460            int violationMask,
8461            StrictMode.ViolationInfo info) {
8462        ProcessRecord r = findAppProcess(app, "StrictMode");
8463        if (r == null) {
8464            return;
8465        }
8466
8467        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8468            Integer stackFingerprint = info.hashCode();
8469            boolean logIt = true;
8470            synchronized (mAlreadyLoggedViolatedStacks) {
8471                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8472                    logIt = false;
8473                    // TODO: sub-sample into EventLog for these, with
8474                    // the info.durationMillis?  Then we'd get
8475                    // the relative pain numbers, without logging all
8476                    // the stack traces repeatedly.  We'd want to do
8477                    // likewise in the client code, which also does
8478                    // dup suppression, before the Binder call.
8479                } else {
8480                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8481                        mAlreadyLoggedViolatedStacks.clear();
8482                    }
8483                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8484                }
8485            }
8486            if (logIt) {
8487                logStrictModeViolationToDropBox(r, info);
8488            }
8489        }
8490
8491        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8492            AppErrorResult result = new AppErrorResult();
8493            synchronized (this) {
8494                final long origId = Binder.clearCallingIdentity();
8495
8496                Message msg = Message.obtain();
8497                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8498                HashMap<String, Object> data = new HashMap<String, Object>();
8499                data.put("result", result);
8500                data.put("app", r);
8501                data.put("violationMask", violationMask);
8502                data.put("info", info);
8503                msg.obj = data;
8504                mHandler.sendMessage(msg);
8505
8506                Binder.restoreCallingIdentity(origId);
8507            }
8508            int res = result.get();
8509            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8510        }
8511    }
8512
8513    // Depending on the policy in effect, there could be a bunch of
8514    // these in quick succession so we try to batch these together to
8515    // minimize disk writes, number of dropbox entries, and maximize
8516    // compression, by having more fewer, larger records.
8517    private void logStrictModeViolationToDropBox(
8518            ProcessRecord process,
8519            StrictMode.ViolationInfo info) {
8520        if (info == null) {
8521            return;
8522        }
8523        final boolean isSystemApp = process == null ||
8524                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8525                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8526        final String processName = process == null ? "unknown" : process.processName;
8527        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8528        final DropBoxManager dbox = (DropBoxManager)
8529                mContext.getSystemService(Context.DROPBOX_SERVICE);
8530
8531        // Exit early if the dropbox isn't configured to accept this report type.
8532        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8533
8534        boolean bufferWasEmpty;
8535        boolean needsFlush;
8536        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8537        synchronized (sb) {
8538            bufferWasEmpty = sb.length() == 0;
8539            appendDropBoxProcessHeaders(process, processName, sb);
8540            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8541            sb.append("System-App: ").append(isSystemApp).append("\n");
8542            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8543            if (info.violationNumThisLoop != 0) {
8544                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8545            }
8546            if (info.numAnimationsRunning != 0) {
8547                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8548            }
8549            if (info.broadcastIntentAction != null) {
8550                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8551            }
8552            if (info.durationMillis != -1) {
8553                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8554            }
8555            if (info.numInstances != -1) {
8556                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8557            }
8558            if (info.tags != null) {
8559                for (String tag : info.tags) {
8560                    sb.append("Span-Tag: ").append(tag).append("\n");
8561                }
8562            }
8563            sb.append("\n");
8564            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8565                sb.append(info.crashInfo.stackTrace);
8566            }
8567            sb.append("\n");
8568
8569            // Only buffer up to ~64k.  Various logging bits truncate
8570            // things at 128k.
8571            needsFlush = (sb.length() > 64 * 1024);
8572        }
8573
8574        // Flush immediately if the buffer's grown too large, or this
8575        // is a non-system app.  Non-system apps are isolated with a
8576        // different tag & policy and not batched.
8577        //
8578        // Batching is useful during internal testing with
8579        // StrictMode settings turned up high.  Without batching,
8580        // thousands of separate files could be created on boot.
8581        if (!isSystemApp || needsFlush) {
8582            new Thread("Error dump: " + dropboxTag) {
8583                @Override
8584                public void run() {
8585                    String report;
8586                    synchronized (sb) {
8587                        report = sb.toString();
8588                        sb.delete(0, sb.length());
8589                        sb.trimToSize();
8590                    }
8591                    if (report.length() != 0) {
8592                        dbox.addText(dropboxTag, report);
8593                    }
8594                }
8595            }.start();
8596            return;
8597        }
8598
8599        // System app batching:
8600        if (!bufferWasEmpty) {
8601            // An existing dropbox-writing thread is outstanding, so
8602            // we don't need to start it up.  The existing thread will
8603            // catch the buffer appends we just did.
8604            return;
8605        }
8606
8607        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8608        // (After this point, we shouldn't access AMS internal data structures.)
8609        new Thread("Error dump: " + dropboxTag) {
8610            @Override
8611            public void run() {
8612                // 5 second sleep to let stacks arrive and be batched together
8613                try {
8614                    Thread.sleep(5000);  // 5 seconds
8615                } catch (InterruptedException e) {}
8616
8617                String errorReport;
8618                synchronized (mStrictModeBuffer) {
8619                    errorReport = mStrictModeBuffer.toString();
8620                    if (errorReport.length() == 0) {
8621                        return;
8622                    }
8623                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8624                    mStrictModeBuffer.trimToSize();
8625                }
8626                dbox.addText(dropboxTag, errorReport);
8627            }
8628        }.start();
8629    }
8630
8631    /**
8632     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8633     * @param app object of the crashing app, null for the system server
8634     * @param tag reported by the caller
8635     * @param crashInfo describing the context of the error
8636     * @return true if the process should exit immediately (WTF is fatal)
8637     */
8638    public boolean handleApplicationWtf(IBinder app, String tag,
8639            ApplicationErrorReport.CrashInfo crashInfo) {
8640        ProcessRecord r = findAppProcess(app, "WTF");
8641        final String processName = app == null ? "system_server"
8642                : (r == null ? "unknown" : r.processName);
8643
8644        EventLog.writeEvent(EventLogTags.AM_WTF,
8645                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8646                processName,
8647                r == null ? -1 : r.info.flags,
8648                tag, crashInfo.exceptionMessage);
8649
8650        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8651
8652        if (r != null && r.pid != Process.myPid() &&
8653                Settings.Global.getInt(mContext.getContentResolver(),
8654                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8655            crashApplication(r, crashInfo);
8656            return true;
8657        } else {
8658            return false;
8659        }
8660    }
8661
8662    /**
8663     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8664     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8665     */
8666    private ProcessRecord findAppProcess(IBinder app, String reason) {
8667        if (app == null) {
8668            return null;
8669        }
8670
8671        synchronized (this) {
8672            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8673                final int NA = apps.size();
8674                for (int ia=0; ia<NA; ia++) {
8675                    ProcessRecord p = apps.valueAt(ia);
8676                    if (p.thread != null && p.thread.asBinder() == app) {
8677                        return p;
8678                    }
8679                }
8680            }
8681
8682            Slog.w(TAG, "Can't find mystery application for " + reason
8683                    + " from pid=" + Binder.getCallingPid()
8684                    + " uid=" + Binder.getCallingUid() + ": " + app);
8685            return null;
8686        }
8687    }
8688
8689    /**
8690     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8691     * to append various headers to the dropbox log text.
8692     */
8693    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8694            StringBuilder sb) {
8695        // Watchdog thread ends up invoking this function (with
8696        // a null ProcessRecord) to add the stack file to dropbox.
8697        // Do not acquire a lock on this (am) in such cases, as it
8698        // could cause a potential deadlock, if and when watchdog
8699        // is invoked due to unavailability of lock on am and it
8700        // would prevent watchdog from killing system_server.
8701        if (process == null) {
8702            sb.append("Process: ").append(processName).append("\n");
8703            return;
8704        }
8705        // Note: ProcessRecord 'process' is guarded by the service
8706        // instance.  (notably process.pkgList, which could otherwise change
8707        // concurrently during execution of this method)
8708        synchronized (this) {
8709            sb.append("Process: ").append(processName).append("\n");
8710            int flags = process.info.flags;
8711            IPackageManager pm = AppGlobals.getPackageManager();
8712            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8713            for (String pkg : process.pkgList) {
8714                sb.append("Package: ").append(pkg);
8715                try {
8716                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8717                    if (pi != null) {
8718                        sb.append(" v").append(pi.versionCode);
8719                        if (pi.versionName != null) {
8720                            sb.append(" (").append(pi.versionName).append(")");
8721                        }
8722                    }
8723                } catch (RemoteException e) {
8724                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8725                }
8726                sb.append("\n");
8727            }
8728        }
8729    }
8730
8731    private static String processClass(ProcessRecord process) {
8732        if (process == null || process.pid == MY_PID) {
8733            return "system_server";
8734        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8735            return "system_app";
8736        } else {
8737            return "data_app";
8738        }
8739    }
8740
8741    /**
8742     * Write a description of an error (crash, WTF, ANR) to the drop box.
8743     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8744     * @param process which caused the error, null means the system server
8745     * @param activity which triggered the error, null if unknown
8746     * @param parent activity related to the error, null if unknown
8747     * @param subject line related to the error, null if absent
8748     * @param report in long form describing the error, null if absent
8749     * @param logFile to include in the report, null if none
8750     * @param crashInfo giving an application stack trace, null if absent
8751     */
8752    public void addErrorToDropBox(String eventType,
8753            ProcessRecord process, String processName, ActivityRecord activity,
8754            ActivityRecord parent, String subject,
8755            final String report, final File logFile,
8756            final ApplicationErrorReport.CrashInfo crashInfo) {
8757        // NOTE -- this must never acquire the ActivityManagerService lock,
8758        // otherwise the watchdog may be prevented from resetting the system.
8759
8760        final String dropboxTag = processClass(process) + "_" + eventType;
8761        final DropBoxManager dbox = (DropBoxManager)
8762                mContext.getSystemService(Context.DROPBOX_SERVICE);
8763
8764        // Exit early if the dropbox isn't configured to accept this report type.
8765        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8766
8767        final StringBuilder sb = new StringBuilder(1024);
8768        appendDropBoxProcessHeaders(process, processName, sb);
8769        if (activity != null) {
8770            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8771        }
8772        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8773            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8774        }
8775        if (parent != null && parent != activity) {
8776            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8777        }
8778        if (subject != null) {
8779            sb.append("Subject: ").append(subject).append("\n");
8780        }
8781        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8782        if (Debug.isDebuggerConnected()) {
8783            sb.append("Debugger: Connected\n");
8784        }
8785        sb.append("\n");
8786
8787        // Do the rest in a worker thread to avoid blocking the caller on I/O
8788        // (After this point, we shouldn't access AMS internal data structures.)
8789        Thread worker = new Thread("Error dump: " + dropboxTag) {
8790            @Override
8791            public void run() {
8792                if (report != null) {
8793                    sb.append(report);
8794                }
8795                if (logFile != null) {
8796                    try {
8797                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8798                    } catch (IOException e) {
8799                        Slog.e(TAG, "Error reading " + logFile, e);
8800                    }
8801                }
8802                if (crashInfo != null && crashInfo.stackTrace != null) {
8803                    sb.append(crashInfo.stackTrace);
8804                }
8805
8806                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8807                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8808                if (lines > 0) {
8809                    sb.append("\n");
8810
8811                    // Merge several logcat streams, and take the last N lines
8812                    InputStreamReader input = null;
8813                    try {
8814                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8815                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8816                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8817
8818                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8819                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8820                        input = new InputStreamReader(logcat.getInputStream());
8821
8822                        int num;
8823                        char[] buf = new char[8192];
8824                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8825                    } catch (IOException e) {
8826                        Slog.e(TAG, "Error running logcat", e);
8827                    } finally {
8828                        if (input != null) try { input.close(); } catch (IOException e) {}
8829                    }
8830                }
8831
8832                dbox.addText(dropboxTag, sb.toString());
8833            }
8834        };
8835
8836        if (process == null) {
8837            // If process is null, we are being called from some internal code
8838            // and may be about to die -- run this synchronously.
8839            worker.run();
8840        } else {
8841            worker.start();
8842        }
8843    }
8844
8845    /**
8846     * Bring up the "unexpected error" dialog box for a crashing app.
8847     * Deal with edge cases (intercepts from instrumented applications,
8848     * ActivityController, error intent receivers, that sort of thing).
8849     * @param r the application crashing
8850     * @param crashInfo describing the failure
8851     */
8852    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8853        long timeMillis = System.currentTimeMillis();
8854        String shortMsg = crashInfo.exceptionClassName;
8855        String longMsg = crashInfo.exceptionMessage;
8856        String stackTrace = crashInfo.stackTrace;
8857        if (shortMsg != null && longMsg != null) {
8858            longMsg = shortMsg + ": " + longMsg;
8859        } else if (shortMsg != null) {
8860            longMsg = shortMsg;
8861        }
8862
8863        AppErrorResult result = new AppErrorResult();
8864        synchronized (this) {
8865            if (mController != null) {
8866                try {
8867                    String name = r != null ? r.processName : null;
8868                    int pid = r != null ? r.pid : Binder.getCallingPid();
8869                    if (!mController.appCrashed(name, pid,
8870                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8871                        Slog.w(TAG, "Force-killing crashed app " + name
8872                                + " at watcher's request");
8873                        Process.killProcess(pid);
8874                        return;
8875                    }
8876                } catch (RemoteException e) {
8877                    mController = null;
8878                    Watchdog.getInstance().setActivityController(null);
8879                }
8880            }
8881
8882            final long origId = Binder.clearCallingIdentity();
8883
8884            // If this process is running instrumentation, finish it.
8885            if (r != null && r.instrumentationClass != null) {
8886                Slog.w(TAG, "Error in app " + r.processName
8887                      + " running instrumentation " + r.instrumentationClass + ":");
8888                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8889                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8890                Bundle info = new Bundle();
8891                info.putString("shortMsg", shortMsg);
8892                info.putString("longMsg", longMsg);
8893                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8894                Binder.restoreCallingIdentity(origId);
8895                return;
8896            }
8897
8898            // If we can't identify the process or it's already exceeded its crash quota,
8899            // quit right away without showing a crash dialog.
8900            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8901                Binder.restoreCallingIdentity(origId);
8902                return;
8903            }
8904
8905            Message msg = Message.obtain();
8906            msg.what = SHOW_ERROR_MSG;
8907            HashMap data = new HashMap();
8908            data.put("result", result);
8909            data.put("app", r);
8910            msg.obj = data;
8911            mHandler.sendMessage(msg);
8912
8913            Binder.restoreCallingIdentity(origId);
8914        }
8915
8916        int res = result.get();
8917
8918        Intent appErrorIntent = null;
8919        synchronized (this) {
8920            if (r != null && !r.isolated) {
8921                // XXX Can't keep track of crash time for isolated processes,
8922                // since they don't have a persistent identity.
8923                mProcessCrashTimes.put(r.info.processName, r.uid,
8924                        SystemClock.uptimeMillis());
8925            }
8926            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8927                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8928            }
8929        }
8930
8931        if (appErrorIntent != null) {
8932            try {
8933                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8934            } catch (ActivityNotFoundException e) {
8935                Slog.w(TAG, "bug report receiver dissappeared", e);
8936            }
8937        }
8938    }
8939
8940    Intent createAppErrorIntentLocked(ProcessRecord r,
8941            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8942        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8943        if (report == null) {
8944            return null;
8945        }
8946        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8947        result.setComponent(r.errorReportReceiver);
8948        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8949        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8950        return result;
8951    }
8952
8953    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8954            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8955        if (r.errorReportReceiver == null) {
8956            return null;
8957        }
8958
8959        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
8960            return null;
8961        }
8962
8963        ApplicationErrorReport report = new ApplicationErrorReport();
8964        report.packageName = r.info.packageName;
8965        report.installerPackageName = r.errorReportReceiver.getPackageName();
8966        report.processName = r.processName;
8967        report.time = timeMillis;
8968        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8969
8970        if (r.crashing || r.forceCrashReport) {
8971            report.type = ApplicationErrorReport.TYPE_CRASH;
8972            report.crashInfo = crashInfo;
8973        } else if (r.notResponding) {
8974            report.type = ApplicationErrorReport.TYPE_ANR;
8975            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8976
8977            report.anrInfo.activity = r.notRespondingReport.tag;
8978            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8979            report.anrInfo.info = r.notRespondingReport.longMsg;
8980        }
8981
8982        return report;
8983    }
8984
8985    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8986        enforceNotIsolatedCaller("getProcessesInErrorState");
8987        // assume our apps are happy - lazy create the list
8988        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8989
8990        final boolean allUsers = ActivityManager.checkUidPermission(
8991                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8992                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8993        int userId = UserHandle.getUserId(Binder.getCallingUid());
8994
8995        synchronized (this) {
8996
8997            // iterate across all processes
8998            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8999                ProcessRecord app = mLruProcesses.get(i);
9000                if (!allUsers && app.userId != userId) {
9001                    continue;
9002                }
9003                if ((app.thread != null) && (app.crashing || app.notResponding)) {
9004                    // This one's in trouble, so we'll generate a report for it
9005                    // crashes are higher priority (in case there's a crash *and* an anr)
9006                    ActivityManager.ProcessErrorStateInfo report = null;
9007                    if (app.crashing) {
9008                        report = app.crashingReport;
9009                    } else if (app.notResponding) {
9010                        report = app.notRespondingReport;
9011                    }
9012
9013                    if (report != null) {
9014                        if (errList == null) {
9015                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
9016                        }
9017                        errList.add(report);
9018                    } else {
9019                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
9020                                " crashing = " + app.crashing +
9021                                " notResponding = " + app.notResponding);
9022                    }
9023                }
9024            }
9025        }
9026
9027        return errList;
9028    }
9029
9030    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
9031        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9032            if (currApp != null) {
9033                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
9034            }
9035            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9036        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
9037            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9038        } else if (adj >= ProcessList.HOME_APP_ADJ) {
9039            if (currApp != null) {
9040                currApp.lru = 0;
9041            }
9042            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9043        } else if (adj >= ProcessList.SERVICE_ADJ) {
9044            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9045        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9046            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
9047        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9048            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
9049        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
9050            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9051        } else {
9052            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9053        }
9054    }
9055
9056    private void fillInProcMemInfo(ProcessRecord app,
9057            ActivityManager.RunningAppProcessInfo outInfo) {
9058        outInfo.pid = app.pid;
9059        outInfo.uid = app.info.uid;
9060        if (mHeavyWeightProcess == app) {
9061            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
9062        }
9063        if (app.persistent) {
9064            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
9065        }
9066        if (app.hasActivities) {
9067            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
9068        }
9069        outInfo.lastTrimLevel = app.trimMemoryLevel;
9070        int adj = app.curAdj;
9071        outInfo.importance = oomAdjToImportance(adj, outInfo);
9072        outInfo.importanceReasonCode = app.adjTypeCode;
9073    }
9074
9075    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9076        enforceNotIsolatedCaller("getRunningAppProcesses");
9077        // Lazy instantiation of list
9078        List<ActivityManager.RunningAppProcessInfo> runList = null;
9079        final boolean allUsers = ActivityManager.checkUidPermission(
9080                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9081                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
9082        int userId = UserHandle.getUserId(Binder.getCallingUid());
9083        synchronized (this) {
9084            // Iterate across all processes
9085            for (int i=mLruProcesses.size()-1; i>=0; i--) {
9086                ProcessRecord app = mLruProcesses.get(i);
9087                if (!allUsers && app.userId != userId) {
9088                    continue;
9089                }
9090                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9091                    // Generate process state info for running application
9092                    ActivityManager.RunningAppProcessInfo currApp =
9093                        new ActivityManager.RunningAppProcessInfo(app.processName,
9094                                app.pid, app.getPackageList());
9095                    fillInProcMemInfo(app, currApp);
9096                    if (app.adjSource instanceof ProcessRecord) {
9097                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9098                        currApp.importanceReasonImportance = oomAdjToImportance(
9099                                app.adjSourceOom, null);
9100                    } else if (app.adjSource instanceof ActivityRecord) {
9101                        ActivityRecord r = (ActivityRecord)app.adjSource;
9102                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9103                    }
9104                    if (app.adjTarget instanceof ComponentName) {
9105                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9106                    }
9107                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9108                    //        + " lru=" + currApp.lru);
9109                    if (runList == null) {
9110                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9111                    }
9112                    runList.add(currApp);
9113                }
9114            }
9115        }
9116        return runList;
9117    }
9118
9119    public List<ApplicationInfo> getRunningExternalApplications() {
9120        enforceNotIsolatedCaller("getRunningExternalApplications");
9121        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
9122        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
9123        if (runningApps != null && runningApps.size() > 0) {
9124            Set<String> extList = new HashSet<String>();
9125            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
9126                if (app.pkgList != null) {
9127                    for (String pkg : app.pkgList) {
9128                        extList.add(pkg);
9129                    }
9130                }
9131            }
9132            IPackageManager pm = AppGlobals.getPackageManager();
9133            for (String pkg : extList) {
9134                try {
9135                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
9136                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
9137                        retList.add(info);
9138                    }
9139                } catch (RemoteException e) {
9140                }
9141            }
9142        }
9143        return retList;
9144    }
9145
9146    @Override
9147    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
9148        enforceNotIsolatedCaller("getMyMemoryState");
9149        synchronized (this) {
9150            ProcessRecord proc;
9151            synchronized (mPidsSelfLocked) {
9152                proc = mPidsSelfLocked.get(Binder.getCallingPid());
9153            }
9154            fillInProcMemInfo(proc, outInfo);
9155        }
9156    }
9157
9158    @Override
9159    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9160        if (checkCallingPermission(android.Manifest.permission.DUMP)
9161                != PackageManager.PERMISSION_GRANTED) {
9162            pw.println("Permission Denial: can't dump ActivityManager from from pid="
9163                    + Binder.getCallingPid()
9164                    + ", uid=" + Binder.getCallingUid()
9165                    + " without permission "
9166                    + android.Manifest.permission.DUMP);
9167            return;
9168        }
9169
9170        boolean dumpAll = false;
9171        boolean dumpClient = false;
9172        String dumpPackage = null;
9173
9174        int opti = 0;
9175        while (opti < args.length) {
9176            String opt = args[opti];
9177            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9178                break;
9179            }
9180            opti++;
9181            if ("-a".equals(opt)) {
9182                dumpAll = true;
9183            } else if ("-c".equals(opt)) {
9184                dumpClient = true;
9185            } else if ("-h".equals(opt)) {
9186                pw.println("Activity manager dump options:");
9187                pw.println("  [-a] [-c] [-h] [cmd] ...");
9188                pw.println("  cmd may be one of:");
9189                pw.println("    a[ctivities]: activity stack state");
9190                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
9191                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
9192                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
9193                pw.println("    o[om]: out of memory management");
9194                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
9195                pw.println("    provider [COMP_SPEC]: provider client-side state");
9196                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
9197                pw.println("    service [COMP_SPEC]: service client-side state");
9198                pw.println("    package [PACKAGE_NAME]: all state related to given package");
9199                pw.println("    all: dump all activities");
9200                pw.println("    top: dump the top activity");
9201                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
9202                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
9203                pw.println("    a partial substring in a component name, a");
9204                pw.println("    hex object identifier.");
9205                pw.println("  -a: include all available server state.");
9206                pw.println("  -c: include client state.");
9207                return;
9208            } else {
9209                pw.println("Unknown argument: " + opt + "; use -h for help");
9210            }
9211        }
9212
9213        long origId = Binder.clearCallingIdentity();
9214        boolean more = false;
9215        // Is the caller requesting to dump a particular piece of data?
9216        if (opti < args.length) {
9217            String cmd = args[opti];
9218            opti++;
9219            if ("activities".equals(cmd) || "a".equals(cmd)) {
9220                synchronized (this) {
9221                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
9222                }
9223            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
9224                String[] newArgs;
9225                String name;
9226                if (opti >= args.length) {
9227                    name = null;
9228                    newArgs = EMPTY_STRING_ARRAY;
9229                } else {
9230                    name = args[opti];
9231                    opti++;
9232                    newArgs = new String[args.length - opti];
9233                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9234                            args.length - opti);
9235                }
9236                synchronized (this) {
9237                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
9238                }
9239            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9240                String[] newArgs;
9241                String name;
9242                if (opti >= args.length) {
9243                    name = null;
9244                    newArgs = EMPTY_STRING_ARRAY;
9245                } else {
9246                    name = args[opti];
9247                    opti++;
9248                    newArgs = new String[args.length - opti];
9249                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9250                            args.length - opti);
9251                }
9252                synchronized (this) {
9253                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
9254                }
9255            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9256                String[] newArgs;
9257                String name;
9258                if (opti >= args.length) {
9259                    name = null;
9260                    newArgs = EMPTY_STRING_ARRAY;
9261                } else {
9262                    name = args[opti];
9263                    opti++;
9264                    newArgs = new String[args.length - opti];
9265                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9266                            args.length - opti);
9267                }
9268                synchronized (this) {
9269                    dumpProcessesLocked(fd, pw, args, opti, true, name);
9270                }
9271            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9272                synchronized (this) {
9273                    dumpOomLocked(fd, pw, args, opti, true);
9274                }
9275            } else if ("provider".equals(cmd)) {
9276                String[] newArgs;
9277                String name;
9278                if (opti >= args.length) {
9279                    name = null;
9280                    newArgs = EMPTY_STRING_ARRAY;
9281                } else {
9282                    name = args[opti];
9283                    opti++;
9284                    newArgs = new String[args.length - opti];
9285                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9286                }
9287                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9288                    pw.println("No providers match: " + name);
9289                    pw.println("Use -h for help.");
9290                }
9291            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9292                synchronized (this) {
9293                    dumpProvidersLocked(fd, pw, args, opti, true, null);
9294                }
9295            } else if ("service".equals(cmd)) {
9296                String[] newArgs;
9297                String name;
9298                if (opti >= args.length) {
9299                    name = null;
9300                    newArgs = EMPTY_STRING_ARRAY;
9301                } else {
9302                    name = args[opti];
9303                    opti++;
9304                    newArgs = new String[args.length - opti];
9305                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9306                            args.length - opti);
9307                }
9308                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9309                    pw.println("No services match: " + name);
9310                    pw.println("Use -h for help.");
9311                }
9312            } else if ("package".equals(cmd)) {
9313                String[] newArgs;
9314                if (opti >= args.length) {
9315                    pw.println("package: no package name specified");
9316                    pw.println("Use -h for help.");
9317                } else {
9318                    dumpPackage = args[opti];
9319                    opti++;
9320                    newArgs = new String[args.length - opti];
9321                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9322                            args.length - opti);
9323                    args = newArgs;
9324                    opti = 0;
9325                    more = true;
9326                }
9327            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9328                synchronized (this) {
9329                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9330                }
9331            } else {
9332                // Dumping a single activity?
9333                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9334                    pw.println("Bad activity command, or no activities match: " + cmd);
9335                    pw.println("Use -h for help.");
9336                }
9337            }
9338            if (!more) {
9339                Binder.restoreCallingIdentity(origId);
9340                return;
9341            }
9342        }
9343
9344        // No piece of data specified, dump everything.
9345        synchronized (this) {
9346            boolean needSep;
9347            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9348            if (needSep) {
9349                pw.println(" ");
9350            }
9351            if (dumpAll) {
9352                pw.println("-------------------------------------------------------------------------------");
9353            }
9354            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9355            if (needSep) {
9356                pw.println(" ");
9357            }
9358            if (dumpAll) {
9359                pw.println("-------------------------------------------------------------------------------");
9360            }
9361            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9362            if (needSep) {
9363                pw.println(" ");
9364            }
9365            if (dumpAll) {
9366                pw.println("-------------------------------------------------------------------------------");
9367            }
9368            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9369            if (needSep) {
9370                pw.println(" ");
9371            }
9372            if (dumpAll) {
9373                pw.println("-------------------------------------------------------------------------------");
9374            }
9375            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9376            if (needSep) {
9377                pw.println(" ");
9378            }
9379            if (dumpAll) {
9380                pw.println("-------------------------------------------------------------------------------");
9381            }
9382            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9383        }
9384        Binder.restoreCallingIdentity(origId);
9385    }
9386
9387    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9388            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9389        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9390        pw.println("  Main stack:");
9391        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9392                dumpPackage);
9393        pw.println(" ");
9394        pw.println("  Running activities (most recent first):");
9395        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9396                dumpPackage);
9397        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9398            pw.println(" ");
9399            pw.println("  Activities waiting for another to become visible:");
9400            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9401                    !dumpAll, false, dumpPackage);
9402        }
9403        if (mMainStack.mStoppingActivities.size() > 0) {
9404            pw.println(" ");
9405            pw.println("  Activities waiting to stop:");
9406            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9407                    !dumpAll, false, dumpPackage);
9408        }
9409        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9410            pw.println(" ");
9411            pw.println("  Activities waiting to sleep:");
9412            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9413                    !dumpAll, false, dumpPackage);
9414        }
9415        if (mMainStack.mFinishingActivities.size() > 0) {
9416            pw.println(" ");
9417            pw.println("  Activities waiting to finish:");
9418            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9419                    !dumpAll, false, dumpPackage);
9420        }
9421
9422        pw.println(" ");
9423        if (mMainStack.mPausingActivity != null) {
9424            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9425        }
9426        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9427        pw.println("  mFocusedActivity: " + mFocusedActivity);
9428        if (dumpAll) {
9429            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9430            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9431            pw.println("  mDismissKeyguardOnNextActivity: "
9432                    + mMainStack.mDismissKeyguardOnNextActivity);
9433        }
9434
9435        if (mRecentTasks.size() > 0) {
9436            pw.println();
9437            pw.println("  Recent tasks:");
9438
9439            final int N = mRecentTasks.size();
9440            for (int i=0; i<N; i++) {
9441                TaskRecord tr = mRecentTasks.get(i);
9442                if (dumpPackage != null) {
9443                    if (tr.realActivity == null ||
9444                            !dumpPackage.equals(tr.realActivity)) {
9445                        continue;
9446                    }
9447                }
9448                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9449                        pw.println(tr);
9450                if (dumpAll) {
9451                    mRecentTasks.get(i).dump(pw, "    ");
9452                }
9453            }
9454        }
9455
9456        if (dumpAll) {
9457            pw.println(" ");
9458            pw.println("  mCurTask: " + mCurTask);
9459        }
9460
9461        return true;
9462    }
9463
9464    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9465            int opti, boolean dumpAll, String dumpPackage) {
9466        boolean needSep = false;
9467        int numPers = 0;
9468
9469        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9470
9471        if (dumpAll) {
9472            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9473                final int NA = procs.size();
9474                for (int ia=0; ia<NA; ia++) {
9475                    ProcessRecord r = procs.valueAt(ia);
9476                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9477                        continue;
9478                    }
9479                    if (!needSep) {
9480                        pw.println("  All known processes:");
9481                        needSep = true;
9482                    }
9483                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9484                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9485                        pw.print(" "); pw.println(r);
9486                    r.dump(pw, "    ");
9487                    if (r.persistent) {
9488                        numPers++;
9489                    }
9490                }
9491            }
9492        }
9493
9494        if (mIsolatedProcesses.size() > 0) {
9495            if (needSep) pw.println(" ");
9496            needSep = true;
9497            pw.println("  Isolated process list (sorted by uid):");
9498            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9499                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9500                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9501                    continue;
9502                }
9503                pw.println(String.format("%sIsolated #%2d: %s",
9504                        "    ", i, r.toString()));
9505            }
9506        }
9507
9508        if (mLruProcesses.size() > 0) {
9509            if (needSep) pw.println(" ");
9510            needSep = true;
9511            pw.println("  Process LRU list (sorted by oom_adj):");
9512            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9513                    "Proc", "PERS", false, dumpPackage);
9514            needSep = true;
9515        }
9516
9517        if (dumpAll) {
9518            synchronized (mPidsSelfLocked) {
9519                boolean printed = false;
9520                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9521                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9522                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9523                        continue;
9524                    }
9525                    if (!printed) {
9526                        if (needSep) pw.println(" ");
9527                        needSep = true;
9528                        pw.println("  PID mappings:");
9529                        printed = true;
9530                    }
9531                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9532                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9533                }
9534            }
9535        }
9536
9537        if (mForegroundProcesses.size() > 0) {
9538            synchronized (mPidsSelfLocked) {
9539                boolean printed = false;
9540                for (int i=0; i<mForegroundProcesses.size(); i++) {
9541                    ProcessRecord r = mPidsSelfLocked.get(
9542                            mForegroundProcesses.valueAt(i).pid);
9543                    if (dumpPackage != null && (r == null
9544                            || !dumpPackage.equals(r.info.packageName))) {
9545                        continue;
9546                    }
9547                    if (!printed) {
9548                        if (needSep) pw.println(" ");
9549                        needSep = true;
9550                        pw.println("  Foreground Processes:");
9551                        printed = true;
9552                    }
9553                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9554                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9555                }
9556            }
9557        }
9558
9559        if (mPersistentStartingProcesses.size() > 0) {
9560            if (needSep) pw.println(" ");
9561            needSep = true;
9562            pw.println("  Persisent processes that are starting:");
9563            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9564                    "Starting Norm", "Restarting PERS", dumpPackage);
9565        }
9566
9567        if (mRemovedProcesses.size() > 0) {
9568            if (needSep) pw.println(" ");
9569            needSep = true;
9570            pw.println("  Processes that are being removed:");
9571            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9572                    "Removed Norm", "Removed PERS", dumpPackage);
9573        }
9574
9575        if (mProcessesOnHold.size() > 0) {
9576            if (needSep) pw.println(" ");
9577            needSep = true;
9578            pw.println("  Processes that are on old until the system is ready:");
9579            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9580                    "OnHold Norm", "OnHold PERS", dumpPackage);
9581        }
9582
9583        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9584
9585        if (mProcessCrashTimes.getMap().size() > 0) {
9586            boolean printed = false;
9587            long now = SystemClock.uptimeMillis();
9588            for (Map.Entry<String, SparseArray<Long>> procs
9589                    : mProcessCrashTimes.getMap().entrySet()) {
9590                String pname = procs.getKey();
9591                SparseArray<Long> uids = procs.getValue();
9592                final int N = uids.size();
9593                for (int i=0; i<N; i++) {
9594                    int puid = uids.keyAt(i);
9595                    ProcessRecord r = mProcessNames.get(pname, puid);
9596                    if (dumpPackage != null && (r == null
9597                            || !dumpPackage.equals(r.info.packageName))) {
9598                        continue;
9599                    }
9600                    if (!printed) {
9601                        if (needSep) pw.println(" ");
9602                        needSep = true;
9603                        pw.println("  Time since processes crashed:");
9604                        printed = true;
9605                    }
9606                    pw.print("    Process "); pw.print(pname);
9607                            pw.print(" uid "); pw.print(puid);
9608                            pw.print(": last crashed ");
9609                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9610                            pw.println(" ago");
9611                }
9612            }
9613        }
9614
9615        if (mBadProcesses.getMap().size() > 0) {
9616            boolean printed = false;
9617            for (Map.Entry<String, SparseArray<Long>> procs
9618                    : mBadProcesses.getMap().entrySet()) {
9619                String pname = procs.getKey();
9620                SparseArray<Long> uids = procs.getValue();
9621                final int N = uids.size();
9622                for (int i=0; i<N; i++) {
9623                    int puid = uids.keyAt(i);
9624                    ProcessRecord r = mProcessNames.get(pname, puid);
9625                    if (dumpPackage != null && (r == null
9626                            || !dumpPackage.equals(r.info.packageName))) {
9627                        continue;
9628                    }
9629                    if (!printed) {
9630                        if (needSep) pw.println(" ");
9631                        needSep = true;
9632                        pw.println("  Bad processes:");
9633                    }
9634                    pw.print("    Bad process "); pw.print(pname);
9635                            pw.print(" uid "); pw.print(puid);
9636                            pw.print(": crashed at time ");
9637                            pw.println(uids.valueAt(i));
9638                }
9639            }
9640        }
9641
9642        pw.println();
9643        pw.println("  mStartedUsers:");
9644        for (int i=0; i<mStartedUsers.size(); i++) {
9645            UserStartedState uss = mStartedUsers.valueAt(i);
9646            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9647                    pw.print(": "); uss.dump("", pw);
9648        }
9649        pw.print("  mStartedUserArray: [");
9650        for (int i=0; i<mStartedUserArray.length; i++) {
9651            if (i > 0) pw.print(", ");
9652            pw.print(mStartedUserArray[i]);
9653        }
9654        pw.println("]");
9655        pw.print("  mUserLru: [");
9656        for (int i=0; i<mUserLru.size(); i++) {
9657            if (i > 0) pw.print(", ");
9658            pw.print(mUserLru.get(i));
9659        }
9660        pw.println("]");
9661        if (dumpAll) {
9662            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9663        }
9664        pw.println("  mHomeProcess: " + mHomeProcess);
9665        pw.println("  mPreviousProcess: " + mPreviousProcess);
9666        if (dumpAll) {
9667            StringBuilder sb = new StringBuilder(128);
9668            sb.append("  mPreviousProcessVisibleTime: ");
9669            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9670            pw.println(sb);
9671        }
9672        if (mHeavyWeightProcess != null) {
9673            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9674        }
9675        pw.println("  mConfiguration: " + mConfiguration);
9676        if (dumpAll) {
9677            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9678            if (mCompatModePackages.getPackages().size() > 0) {
9679                boolean printed = false;
9680                for (Map.Entry<String, Integer> entry
9681                        : mCompatModePackages.getPackages().entrySet()) {
9682                    String pkg = entry.getKey();
9683                    int mode = entry.getValue();
9684                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9685                        continue;
9686                    }
9687                    if (!printed) {
9688                        pw.println("  mScreenCompatPackages:");
9689                        printed = true;
9690                    }
9691                    pw.print("    "); pw.print(pkg); pw.print(": ");
9692                            pw.print(mode); pw.println();
9693                }
9694            }
9695        }
9696        if (mSleeping || mWentToSleep || mLockScreenShown) {
9697            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9698                    + " mLockScreenShown " + mLockScreenShown);
9699        }
9700        if (mShuttingDown) {
9701            pw.println("  mShuttingDown=" + mShuttingDown);
9702        }
9703        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9704                || mOrigWaitForDebugger) {
9705            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9706                    + " mDebugTransient=" + mDebugTransient
9707                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9708        }
9709        if (mOpenGlTraceApp != null) {
9710            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9711        }
9712        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9713                || mProfileFd != null) {
9714            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9715            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9716            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9717                    + mAutoStopProfiler);
9718        }
9719        if (mAlwaysFinishActivities || mController != null) {
9720            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9721                    + " mController=" + mController);
9722        }
9723        if (dumpAll) {
9724            pw.println("  Total persistent processes: " + numPers);
9725            pw.println("  mStartRunning=" + mStartRunning
9726                    + " mProcessesReady=" + mProcessesReady
9727                    + " mSystemReady=" + mSystemReady);
9728            pw.println("  mBooting=" + mBooting
9729                    + " mBooted=" + mBooted
9730                    + " mFactoryTest=" + mFactoryTest);
9731            pw.print("  mLastPowerCheckRealtime=");
9732                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9733                    pw.println("");
9734            pw.print("  mLastPowerCheckUptime=");
9735                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9736                    pw.println("");
9737            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9738            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9739            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9740            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9741                    + " mNumHiddenProcs=" + mNumHiddenProcs
9742                    + " mNumServiceProcs=" + mNumServiceProcs
9743                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9744        }
9745
9746        return true;
9747    }
9748
9749    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9750            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9751        if (mProcessesToGc.size() > 0) {
9752            boolean printed = false;
9753            long now = SystemClock.uptimeMillis();
9754            for (int i=0; i<mProcessesToGc.size(); i++) {
9755                ProcessRecord proc = mProcessesToGc.get(i);
9756                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9757                    continue;
9758                }
9759                if (!printed) {
9760                    if (needSep) pw.println(" ");
9761                    needSep = true;
9762                    pw.println("  Processes that are waiting to GC:");
9763                    printed = true;
9764                }
9765                pw.print("    Process "); pw.println(proc);
9766                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9767                        pw.print(", last gced=");
9768                        pw.print(now-proc.lastRequestedGc);
9769                        pw.print(" ms ago, last lowMem=");
9770                        pw.print(now-proc.lastLowMemory);
9771                        pw.println(" ms ago");
9772
9773            }
9774        }
9775        return needSep;
9776    }
9777
9778    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9779            int opti, boolean dumpAll) {
9780        boolean needSep = false;
9781
9782        if (mLruProcesses.size() > 0) {
9783            if (needSep) pw.println(" ");
9784            needSep = true;
9785            pw.println("  OOM levels:");
9786            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9787            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9788            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9789            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9790            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9791            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9792            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9793            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9794            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9795            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9796            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9797            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9798            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9799
9800            if (needSep) pw.println(" ");
9801            needSep = true;
9802            pw.println("  Process OOM control:");
9803            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9804                    "Proc", "PERS", true, null);
9805            needSep = true;
9806        }
9807
9808        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9809
9810        pw.println();
9811        pw.println("  mHomeProcess: " + mHomeProcess);
9812        pw.println("  mPreviousProcess: " + mPreviousProcess);
9813        if (mHeavyWeightProcess != null) {
9814            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9815        }
9816
9817        return true;
9818    }
9819
9820    /**
9821     * There are three ways to call this:
9822     *  - no provider specified: dump all the providers
9823     *  - a flattened component name that matched an existing provider was specified as the
9824     *    first arg: dump that one provider
9825     *  - the first arg isn't the flattened component name of an existing provider:
9826     *    dump all providers whose component contains the first arg as a substring
9827     */
9828    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9829            int opti, boolean dumpAll) {
9830        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9831    }
9832
9833    static class ItemMatcher {
9834        ArrayList<ComponentName> components;
9835        ArrayList<String> strings;
9836        ArrayList<Integer> objects;
9837        boolean all;
9838
9839        ItemMatcher() {
9840            all = true;
9841        }
9842
9843        void build(String name) {
9844            ComponentName componentName = ComponentName.unflattenFromString(name);
9845            if (componentName != null) {
9846                if (components == null) {
9847                    components = new ArrayList<ComponentName>();
9848                }
9849                components.add(componentName);
9850                all = false;
9851            } else {
9852                int objectId = 0;
9853                // Not a '/' separated full component name; maybe an object ID?
9854                try {
9855                    objectId = Integer.parseInt(name, 16);
9856                    if (objects == null) {
9857                        objects = new ArrayList<Integer>();
9858                    }
9859                    objects.add(objectId);
9860                    all = false;
9861                } catch (RuntimeException e) {
9862                    // Not an integer; just do string match.
9863                    if (strings == null) {
9864                        strings = new ArrayList<String>();
9865                    }
9866                    strings.add(name);
9867                    all = false;
9868                }
9869            }
9870        }
9871
9872        int build(String[] args, int opti) {
9873            for (; opti<args.length; opti++) {
9874                String name = args[opti];
9875                if ("--".equals(name)) {
9876                    return opti+1;
9877                }
9878                build(name);
9879            }
9880            return opti;
9881        }
9882
9883        boolean match(Object object, ComponentName comp) {
9884            if (all) {
9885                return true;
9886            }
9887            if (components != null) {
9888                for (int i=0; i<components.size(); i++) {
9889                    if (components.get(i).equals(comp)) {
9890                        return true;
9891                    }
9892                }
9893            }
9894            if (objects != null) {
9895                for (int i=0; i<objects.size(); i++) {
9896                    if (System.identityHashCode(object) == objects.get(i)) {
9897                        return true;
9898                    }
9899                }
9900            }
9901            if (strings != null) {
9902                String flat = comp.flattenToString();
9903                for (int i=0; i<strings.size(); i++) {
9904                    if (flat.contains(strings.get(i))) {
9905                        return true;
9906                    }
9907                }
9908            }
9909            return false;
9910        }
9911    }
9912
9913    /**
9914     * There are three things that cmd can be:
9915     *  - a flattened component name that matches an existing activity
9916     *  - the cmd arg isn't the flattened component name of an existing activity:
9917     *    dump all activity whose component contains the cmd as a substring
9918     *  - A hex number of the ActivityRecord object instance.
9919     */
9920    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9921            int opti, boolean dumpAll) {
9922        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9923
9924        if ("all".equals(name)) {
9925            synchronized (this) {
9926                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9927                    activities.add(r1);
9928                }
9929            }
9930        } else if ("top".equals(name)) {
9931            synchronized (this) {
9932                final int N = mMainStack.mHistory.size();
9933                if (N > 0) {
9934                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9935                }
9936            }
9937        } else {
9938            ItemMatcher matcher = new ItemMatcher();
9939            matcher.build(name);
9940
9941            synchronized (this) {
9942                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9943                    if (matcher.match(r1, r1.intent.getComponent())) {
9944                        activities.add(r1);
9945                    }
9946                }
9947            }
9948        }
9949
9950        if (activities.size() <= 0) {
9951            return false;
9952        }
9953
9954        String[] newArgs = new String[args.length - opti];
9955        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9956
9957        TaskRecord lastTask = null;
9958        boolean needSep = false;
9959        for (int i=activities.size()-1; i>=0; i--) {
9960            ActivityRecord r = (ActivityRecord)activities.get(i);
9961            if (needSep) {
9962                pw.println();
9963            }
9964            needSep = true;
9965            synchronized (this) {
9966                if (lastTask != r.task) {
9967                    lastTask = r.task;
9968                    pw.print("TASK "); pw.print(lastTask.affinity);
9969                            pw.print(" id="); pw.println(lastTask.taskId);
9970                    if (dumpAll) {
9971                        lastTask.dump(pw, "  ");
9972                    }
9973                }
9974            }
9975            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9976        }
9977        return true;
9978    }
9979
9980    /**
9981     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9982     * there is a thread associated with the activity.
9983     */
9984    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9985            final ActivityRecord r, String[] args, boolean dumpAll) {
9986        String innerPrefix = prefix + "  ";
9987        synchronized (this) {
9988            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9989                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9990                    pw.print(" pid=");
9991                    if (r.app != null) pw.println(r.app.pid);
9992                    else pw.println("(not running)");
9993            if (dumpAll) {
9994                r.dump(pw, innerPrefix);
9995            }
9996        }
9997        if (r.app != null && r.app.thread != null) {
9998            // flush anything that is already in the PrintWriter since the thread is going
9999            // to write to the file descriptor directly
10000            pw.flush();
10001            try {
10002                TransferPipe tp = new TransferPipe();
10003                try {
10004                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10005                            r.appToken, innerPrefix, args);
10006                    tp.go(fd);
10007                } finally {
10008                    tp.kill();
10009                }
10010            } catch (IOException e) {
10011                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10012            } catch (RemoteException e) {
10013                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10014            }
10015        }
10016    }
10017
10018    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10019            int opti, boolean dumpAll, String dumpPackage) {
10020        boolean needSep = false;
10021        boolean onlyHistory = false;
10022
10023        if ("history".equals(dumpPackage)) {
10024            if (opti < args.length && "-s".equals(args[opti])) {
10025                dumpAll = false;
10026            }
10027            onlyHistory = true;
10028            dumpPackage = null;
10029        }
10030
10031        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
10032        if (!onlyHistory && dumpAll) {
10033            if (mRegisteredReceivers.size() > 0) {
10034                boolean printed = false;
10035                Iterator it = mRegisteredReceivers.values().iterator();
10036                while (it.hasNext()) {
10037                    ReceiverList r = (ReceiverList)it.next();
10038                    if (dumpPackage != null && (r.app == null ||
10039                            !dumpPackage.equals(r.app.info.packageName))) {
10040                        continue;
10041                    }
10042                    if (!printed) {
10043                        pw.println("  Registered Receivers:");
10044                        needSep = true;
10045                        printed = true;
10046                    }
10047                    pw.print("  * "); pw.println(r);
10048                    r.dump(pw, "    ");
10049                }
10050            }
10051
10052            if (mReceiverResolver.dump(pw, needSep ?
10053                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
10054                    "    ", dumpPackage, false)) {
10055                needSep = true;
10056            }
10057        }
10058
10059        for (BroadcastQueue q : mBroadcastQueues) {
10060            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
10061        }
10062
10063        needSep = true;
10064
10065        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
10066            for (int user=0; user<mStickyBroadcasts.size(); user++) {
10067                if (needSep) {
10068                    pw.println();
10069                }
10070                needSep = true;
10071                pw.print("  Sticky broadcasts for user ");
10072                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
10073                StringBuilder sb = new StringBuilder(128);
10074                for (Map.Entry<String, ArrayList<Intent>> ent
10075                        : mStickyBroadcasts.valueAt(user).entrySet()) {
10076                    pw.print("  * Sticky action "); pw.print(ent.getKey());
10077                    if (dumpAll) {
10078                        pw.println(":");
10079                        ArrayList<Intent> intents = ent.getValue();
10080                        final int N = intents.size();
10081                        for (int i=0; i<N; i++) {
10082                            sb.setLength(0);
10083                            sb.append("    Intent: ");
10084                            intents.get(i).toShortString(sb, false, true, false, false);
10085                            pw.println(sb.toString());
10086                            Bundle bundle = intents.get(i).getExtras();
10087                            if (bundle != null) {
10088                                pw.print("      ");
10089                                pw.println(bundle.toString());
10090                            }
10091                        }
10092                    } else {
10093                        pw.println("");
10094                    }
10095                }
10096            }
10097        }
10098
10099        if (!onlyHistory && dumpAll) {
10100            pw.println();
10101            for (BroadcastQueue queue : mBroadcastQueues) {
10102                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
10103                        + queue.mBroadcastsScheduled);
10104            }
10105            pw.println("  mHandler:");
10106            mHandler.dump(new PrintWriterPrinter(pw), "    ");
10107            needSep = true;
10108        }
10109
10110        return needSep;
10111    }
10112
10113    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10114            int opti, boolean dumpAll, String dumpPackage) {
10115        boolean needSep = true;
10116
10117        ItemMatcher matcher = new ItemMatcher();
10118        matcher.build(args, opti);
10119
10120        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
10121
10122        mProviderMap.dumpProvidersLocked(pw, dumpAll);
10123
10124        if (mLaunchingProviders.size() > 0) {
10125            boolean printed = false;
10126            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
10127                ContentProviderRecord r = mLaunchingProviders.get(i);
10128                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10129                    continue;
10130                }
10131                if (!printed) {
10132                    if (needSep) pw.println(" ");
10133                    needSep = true;
10134                    pw.println("  Launching content providers:");
10135                    printed = true;
10136                }
10137                pw.print("  Launching #"); pw.print(i); pw.print(": ");
10138                        pw.println(r);
10139            }
10140        }
10141
10142        if (mGrantedUriPermissions.size() > 0) {
10143            if (needSep) pw.println();
10144            needSep = true;
10145            pw.println("Granted Uri Permissions:");
10146            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10147                int uid = mGrantedUriPermissions.keyAt(i);
10148                HashMap<Uri, UriPermission> perms
10149                        = mGrantedUriPermissions.valueAt(i);
10150                pw.print("  * UID "); pw.print(uid);
10151                        pw.println(" holds:");
10152                for (UriPermission perm : perms.values()) {
10153                    pw.print("    "); pw.println(perm);
10154                    if (dumpAll) {
10155                        perm.dump(pw, "      ");
10156                    }
10157                }
10158            }
10159            needSep = true;
10160        }
10161
10162        return needSep;
10163    }
10164
10165    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10166            int opti, boolean dumpAll, String dumpPackage) {
10167        boolean needSep = false;
10168
10169        if (mIntentSenderRecords.size() > 0) {
10170            boolean printed = false;
10171            Iterator<WeakReference<PendingIntentRecord>> it
10172                    = mIntentSenderRecords.values().iterator();
10173            while (it.hasNext()) {
10174                WeakReference<PendingIntentRecord> ref = it.next();
10175                PendingIntentRecord rec = ref != null ? ref.get(): null;
10176                if (dumpPackage != null && (rec == null
10177                        || !dumpPackage.equals(rec.key.packageName))) {
10178                    continue;
10179                }
10180                if (!printed) {
10181                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10182                    printed = true;
10183                }
10184                needSep = true;
10185                if (rec != null) {
10186                    pw.print("  * "); pw.println(rec);
10187                    if (dumpAll) {
10188                        rec.dump(pw, "    ");
10189                    }
10190                } else {
10191                    pw.print("  * "); pw.println(ref);
10192                }
10193            }
10194        }
10195
10196        return needSep;
10197    }
10198
10199    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
10200            String prefix, String label, boolean complete, boolean brief, boolean client,
10201            String dumpPackage) {
10202        TaskRecord lastTask = null;
10203        boolean needNL = false;
10204        final String innerPrefix = prefix + "      ";
10205        final String[] args = new String[0];
10206        for (int i=list.size()-1; i>=0; i--) {
10207            final ActivityRecord r = (ActivityRecord)list.get(i);
10208            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10209                continue;
10210            }
10211            final boolean full = !brief && (complete || !r.isInHistory());
10212            if (needNL) {
10213                pw.println(" ");
10214                needNL = false;
10215            }
10216            if (lastTask != r.task) {
10217                lastTask = r.task;
10218                pw.print(prefix);
10219                pw.print(full ? "* " : "  ");
10220                pw.println(lastTask);
10221                if (full) {
10222                    lastTask.dump(pw, prefix + "  ");
10223                } else if (complete) {
10224                    // Complete + brief == give a summary.  Isn't that obvious?!?
10225                    if (lastTask.intent != null) {
10226                        pw.print(prefix); pw.print("  ");
10227                                pw.println(lastTask.intent.toInsecureStringWithClip());
10228                    }
10229                }
10230            }
10231            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
10232            pw.print(" #"); pw.print(i); pw.print(": ");
10233            pw.println(r);
10234            if (full) {
10235                r.dump(pw, innerPrefix);
10236            } else if (complete) {
10237                // Complete + brief == give a summary.  Isn't that obvious?!?
10238                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
10239                if (r.app != null) {
10240                    pw.print(innerPrefix); pw.println(r.app);
10241                }
10242            }
10243            if (client && r.app != null && r.app.thread != null) {
10244                // flush anything that is already in the PrintWriter since the thread is going
10245                // to write to the file descriptor directly
10246                pw.flush();
10247                try {
10248                    TransferPipe tp = new TransferPipe();
10249                    try {
10250                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10251                                r.appToken, innerPrefix, args);
10252                        // Short timeout, since blocking here can
10253                        // deadlock with the application.
10254                        tp.go(fd, 2000);
10255                    } finally {
10256                        tp.kill();
10257                    }
10258                } catch (IOException e) {
10259                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10260                } catch (RemoteException e) {
10261                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10262                }
10263                needNL = true;
10264            }
10265        }
10266    }
10267
10268    private static String buildOomTag(String prefix, String space, int val, int base) {
10269        if (val == base) {
10270            if (space == null) return prefix;
10271            return prefix + "  ";
10272        }
10273        return prefix + "+" + Integer.toString(val-base);
10274    }
10275
10276    private static final int dumpProcessList(PrintWriter pw,
10277            ActivityManagerService service, List list,
10278            String prefix, String normalLabel, String persistentLabel,
10279            String dumpPackage) {
10280        int numPers = 0;
10281        final int N = list.size()-1;
10282        for (int i=N; i>=0; i--) {
10283            ProcessRecord r = (ProcessRecord)list.get(i);
10284            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10285                continue;
10286            }
10287            pw.println(String.format("%s%s #%2d: %s",
10288                    prefix, (r.persistent ? persistentLabel : normalLabel),
10289                    i, r.toString()));
10290            if (r.persistent) {
10291                numPers++;
10292            }
10293        }
10294        return numPers;
10295    }
10296
10297    private static final boolean dumpProcessOomList(PrintWriter pw,
10298            ActivityManagerService service, List<ProcessRecord> origList,
10299            String prefix, String normalLabel, String persistentLabel,
10300            boolean inclDetails, String dumpPackage) {
10301
10302        ArrayList<Pair<ProcessRecord, Integer>> list
10303                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10304        for (int i=0; i<origList.size(); i++) {
10305            ProcessRecord r = origList.get(i);
10306            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10307                continue;
10308            }
10309            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10310        }
10311
10312        if (list.size() <= 0) {
10313            return false;
10314        }
10315
10316        Comparator<Pair<ProcessRecord, Integer>> comparator
10317                = new Comparator<Pair<ProcessRecord, Integer>>() {
10318            @Override
10319            public int compare(Pair<ProcessRecord, Integer> object1,
10320                    Pair<ProcessRecord, Integer> object2) {
10321                if (object1.first.setAdj != object2.first.setAdj) {
10322                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10323                }
10324                if (object1.second.intValue() != object2.second.intValue()) {
10325                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10326                }
10327                return 0;
10328            }
10329        };
10330
10331        Collections.sort(list, comparator);
10332
10333        final long curRealtime = SystemClock.elapsedRealtime();
10334        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10335        final long curUptime = SystemClock.uptimeMillis();
10336        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10337
10338        for (int i=list.size()-1; i>=0; i--) {
10339            ProcessRecord r = list.get(i).first;
10340            String oomAdj;
10341            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10342                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10343            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10344                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10345            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10346                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10347            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10348                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10349            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10350                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10351            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10352                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10353            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10354                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10355            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10356                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10357            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10358                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10359            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10360                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10361            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10362                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10363            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10364                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10365            } else {
10366                oomAdj = Integer.toString(r.setAdj);
10367            }
10368            String schedGroup;
10369            switch (r.setSchedGroup) {
10370                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10371                    schedGroup = "B";
10372                    break;
10373                case Process.THREAD_GROUP_DEFAULT:
10374                    schedGroup = "F";
10375                    break;
10376                default:
10377                    schedGroup = Integer.toString(r.setSchedGroup);
10378                    break;
10379            }
10380            String foreground;
10381            if (r.foregroundActivities) {
10382                foreground = "A";
10383            } else if (r.foregroundServices) {
10384                foreground = "S";
10385            } else {
10386                foreground = " ";
10387            }
10388            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10389                    prefix, (r.persistent ? persistentLabel : normalLabel),
10390                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10391                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10392            if (r.adjSource != null || r.adjTarget != null) {
10393                pw.print(prefix);
10394                pw.print("    ");
10395                if (r.adjTarget instanceof ComponentName) {
10396                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10397                } else if (r.adjTarget != null) {
10398                    pw.print(r.adjTarget.toString());
10399                } else {
10400                    pw.print("{null}");
10401                }
10402                pw.print("<=");
10403                if (r.adjSource instanceof ProcessRecord) {
10404                    pw.print("Proc{");
10405                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10406                    pw.println("}");
10407                } else if (r.adjSource != null) {
10408                    pw.println(r.adjSource.toString());
10409                } else {
10410                    pw.println("{null}");
10411                }
10412            }
10413            if (inclDetails) {
10414                pw.print(prefix);
10415                pw.print("    ");
10416                pw.print("oom: max="); pw.print(r.maxAdj);
10417                pw.print(" hidden="); pw.print(r.hiddenAdj);
10418                pw.print(" client="); pw.print(r.clientHiddenAdj);
10419                pw.print(" empty="); pw.print(r.emptyAdj);
10420                pw.print(" curRaw="); pw.print(r.curRawAdj);
10421                pw.print(" setRaw="); pw.print(r.setRawAdj);
10422                pw.print(" cur="); pw.print(r.curAdj);
10423                pw.print(" set="); pw.println(r.setAdj);
10424                pw.print(prefix);
10425                pw.print("    ");
10426                pw.print("keeping="); pw.print(r.keeping);
10427                pw.print(" hidden="); pw.print(r.hidden);
10428                pw.print(" empty="); pw.print(r.empty);
10429                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10430
10431                if (!r.keeping) {
10432                    if (r.lastWakeTime != 0) {
10433                        long wtime;
10434                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10435                        synchronized (stats) {
10436                            wtime = stats.getProcessWakeTime(r.info.uid,
10437                                    r.pid, curRealtime);
10438                        }
10439                        long timeUsed = wtime - r.lastWakeTime;
10440                        pw.print(prefix);
10441                        pw.print("    ");
10442                        pw.print("keep awake over ");
10443                        TimeUtils.formatDuration(realtimeSince, pw);
10444                        pw.print(" used ");
10445                        TimeUtils.formatDuration(timeUsed, pw);
10446                        pw.print(" (");
10447                        pw.print((timeUsed*100)/realtimeSince);
10448                        pw.println("%)");
10449                    }
10450                    if (r.lastCpuTime != 0) {
10451                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10452                        pw.print(prefix);
10453                        pw.print("    ");
10454                        pw.print("run cpu over ");
10455                        TimeUtils.formatDuration(uptimeSince, pw);
10456                        pw.print(" used ");
10457                        TimeUtils.formatDuration(timeUsed, pw);
10458                        pw.print(" (");
10459                        pw.print((timeUsed*100)/uptimeSince);
10460                        pw.println("%)");
10461                    }
10462                }
10463            }
10464        }
10465        return true;
10466    }
10467
10468    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10469        ArrayList<ProcessRecord> procs;
10470        synchronized (this) {
10471            if (args != null && args.length > start
10472                    && args[start].charAt(0) != '-') {
10473                procs = new ArrayList<ProcessRecord>();
10474                int pid = -1;
10475                try {
10476                    pid = Integer.parseInt(args[start]);
10477                } catch (NumberFormatException e) {
10478
10479                }
10480                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10481                    ProcessRecord proc = mLruProcesses.get(i);
10482                    if (proc.pid == pid) {
10483                        procs.add(proc);
10484                    } else if (proc.processName.equals(args[start])) {
10485                        procs.add(proc);
10486                    }
10487                }
10488                if (procs.size() <= 0) {
10489                    pw.println("No process found for: " + args[start]);
10490                    return null;
10491                }
10492            } else {
10493                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10494            }
10495        }
10496        return procs;
10497    }
10498
10499    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10500            PrintWriter pw, String[] args) {
10501        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10502        if (procs == null) {
10503            return;
10504        }
10505
10506        long uptime = SystemClock.uptimeMillis();
10507        long realtime = SystemClock.elapsedRealtime();
10508        pw.println("Applications Graphics Acceleration Info:");
10509        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10510
10511        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10512            ProcessRecord r = procs.get(i);
10513            if (r.thread != null) {
10514                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10515                pw.flush();
10516                try {
10517                    TransferPipe tp = new TransferPipe();
10518                    try {
10519                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10520                        tp.go(fd);
10521                    } finally {
10522                        tp.kill();
10523                    }
10524                } catch (IOException e) {
10525                    pw.println("Failure while dumping the app: " + r);
10526                    pw.flush();
10527                } catch (RemoteException e) {
10528                    pw.println("Got a RemoteException while dumping the app " + r);
10529                    pw.flush();
10530                }
10531            }
10532        }
10533    }
10534
10535    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10536        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10537        if (procs == null) {
10538            return;
10539        }
10540
10541        pw.println("Applications Database Info:");
10542
10543        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10544            ProcessRecord r = procs.get(i);
10545            if (r.thread != null) {
10546                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10547                pw.flush();
10548                try {
10549                    TransferPipe tp = new TransferPipe();
10550                    try {
10551                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10552                        tp.go(fd);
10553                    } finally {
10554                        tp.kill();
10555                    }
10556                } catch (IOException e) {
10557                    pw.println("Failure while dumping the app: " + r);
10558                    pw.flush();
10559                } catch (RemoteException e) {
10560                    pw.println("Got a RemoteException while dumping the app " + r);
10561                    pw.flush();
10562                }
10563            }
10564        }
10565    }
10566
10567    final static class MemItem {
10568        final String label;
10569        final String shortLabel;
10570        final long pss;
10571        final int id;
10572        ArrayList<MemItem> subitems;
10573
10574        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10575            label = _label;
10576            shortLabel = _shortLabel;
10577            pss = _pss;
10578            id = _id;
10579        }
10580    }
10581
10582    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10583            boolean sort) {
10584        if (sort) {
10585            Collections.sort(items, new Comparator<MemItem>() {
10586                @Override
10587                public int compare(MemItem lhs, MemItem rhs) {
10588                    if (lhs.pss < rhs.pss) {
10589                        return 1;
10590                    } else if (lhs.pss > rhs.pss) {
10591                        return -1;
10592                    }
10593                    return 0;
10594                }
10595            });
10596        }
10597
10598        for (int i=0; i<items.size(); i++) {
10599            MemItem mi = items.get(i);
10600            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10601            if (mi.subitems != null) {
10602                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10603            }
10604        }
10605    }
10606
10607    // These are in KB.
10608    static final long[] DUMP_MEM_BUCKETS = new long[] {
10609        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10610        120*1024, 160*1024, 200*1024,
10611        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10612        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10613    };
10614
10615    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10616            boolean stackLike) {
10617        int start = label.lastIndexOf('.');
10618        if (start >= 0) start++;
10619        else start = 0;
10620        int end = label.length();
10621        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10622            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10623                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10624                out.append(bucket);
10625                out.append(stackLike ? "MB." : "MB ");
10626                out.append(label, start, end);
10627                return;
10628            }
10629        }
10630        out.append(memKB/1024);
10631        out.append(stackLike ? "MB." : "MB ");
10632        out.append(label, start, end);
10633    }
10634
10635    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10636            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10637            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10638            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10639            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10640    };
10641    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10642            "System", "Persistent", "Foreground",
10643            "Visible", "Perceptible", "Heavy Weight",
10644            "Backup", "A Services", "Home", "Previous",
10645            "B Services", "Background"
10646    };
10647
10648    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10649            PrintWriter pw, String prefix, String[] args, boolean brief,
10650            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10651        boolean dumpAll = false;
10652        boolean oomOnly = false;
10653
10654        int opti = 0;
10655        while (opti < args.length) {
10656            String opt = args[opti];
10657            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10658                break;
10659            }
10660            opti++;
10661            if ("-a".equals(opt)) {
10662                dumpAll = true;
10663            } else if ("--oom".equals(opt)) {
10664                oomOnly = true;
10665            } else if ("-h".equals(opt)) {
10666                pw.println("meminfo dump options: [-a] [--oom] [process]");
10667                pw.println("  -a: include all available information for each process.");
10668                pw.println("  --oom: only show processes organized by oom adj.");
10669                pw.println("If [process] is specified it can be the name or ");
10670                pw.println("pid of a specific process to dump.");
10671                return;
10672            } else {
10673                pw.println("Unknown argument: " + opt + "; use -h for help");
10674            }
10675        }
10676
10677        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10678        if (procs == null) {
10679            return;
10680        }
10681
10682        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10683        long uptime = SystemClock.uptimeMillis();
10684        long realtime = SystemClock.elapsedRealtime();
10685
10686        if (procs.size() == 1 || isCheckinRequest) {
10687            dumpAll = true;
10688        }
10689
10690        if (isCheckinRequest) {
10691            // short checkin version
10692            pw.println(uptime + "," + realtime);
10693            pw.flush();
10694        } else {
10695            pw.println("Applications Memory Usage (kB):");
10696            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10697        }
10698
10699        String[] innerArgs = new String[args.length-opti];
10700        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10701
10702        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10703        long nativePss=0, dalvikPss=0, otherPss=0;
10704        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10705
10706        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10707        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10708                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10709
10710        long totalPss = 0;
10711
10712        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10713            ProcessRecord r = procs.get(i);
10714            if (r.thread != null) {
10715                if (!isCheckinRequest && dumpAll) {
10716                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10717                    pw.flush();
10718                }
10719                Debug.MemoryInfo mi = null;
10720                if (dumpAll) {
10721                    try {
10722                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10723                    } catch (RemoteException e) {
10724                        if (!isCheckinRequest) {
10725                            pw.println("Got RemoteException!");
10726                            pw.flush();
10727                        }
10728                    }
10729                } else {
10730                    mi = new Debug.MemoryInfo();
10731                    Debug.getMemoryInfo(r.pid, mi);
10732                }
10733
10734                if (!isCheckinRequest && mi != null) {
10735                    long myTotalPss = mi.getTotalPss();
10736                    totalPss += myTotalPss;
10737                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10738                            r.processName, myTotalPss, 0);
10739                    procMems.add(pssItem);
10740
10741                    nativePss += mi.nativePss;
10742                    dalvikPss += mi.dalvikPss;
10743                    otherPss += mi.otherPss;
10744                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10745                        long mem = mi.getOtherPss(j);
10746                        miscPss[j] += mem;
10747                        otherPss -= mem;
10748                    }
10749
10750                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10751                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10752                                || oomIndex == (oomPss.length-1)) {
10753                            oomPss[oomIndex] += myTotalPss;
10754                            if (oomProcs[oomIndex] == null) {
10755                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10756                            }
10757                            oomProcs[oomIndex].add(pssItem);
10758                            break;
10759                        }
10760                    }
10761                }
10762            }
10763        }
10764
10765        if (!isCheckinRequest && procs.size() > 1) {
10766            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10767
10768            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10769            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10770            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10771            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10772                String label = Debug.MemoryInfo.getOtherLabel(j);
10773                catMems.add(new MemItem(label, label, miscPss[j], j));
10774            }
10775
10776            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10777            for (int j=0; j<oomPss.length; j++) {
10778                if (oomPss[j] != 0) {
10779                    String label = DUMP_MEM_OOM_LABEL[j];
10780                    MemItem item = new MemItem(label, label, oomPss[j],
10781                            DUMP_MEM_OOM_ADJ[j]);
10782                    item.subitems = oomProcs[j];
10783                    oomMems.add(item);
10784                }
10785            }
10786
10787            if (outTag != null || outStack != null) {
10788                if (outTag != null) {
10789                    appendMemBucket(outTag, totalPss, "total", false);
10790                }
10791                if (outStack != null) {
10792                    appendMemBucket(outStack, totalPss, "total", true);
10793                }
10794                boolean firstLine = true;
10795                for (int i=0; i<oomMems.size(); i++) {
10796                    MemItem miCat = oomMems.get(i);
10797                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10798                        continue;
10799                    }
10800                    if (miCat.id < ProcessList.SERVICE_ADJ
10801                            || miCat.id == ProcessList.HOME_APP_ADJ
10802                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10803                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10804                            outTag.append(" / ");
10805                        }
10806                        if (outStack != null) {
10807                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10808                                if (firstLine) {
10809                                    outStack.append(":");
10810                                    firstLine = false;
10811                                }
10812                                outStack.append("\n\t at ");
10813                            } else {
10814                                outStack.append("$");
10815                            }
10816                        }
10817                        for (int j=0; j<miCat.subitems.size(); j++) {
10818                            MemItem mi = miCat.subitems.get(j);
10819                            if (j > 0) {
10820                                if (outTag != null) {
10821                                    outTag.append(" ");
10822                                }
10823                                if (outStack != null) {
10824                                    outStack.append("$");
10825                                }
10826                            }
10827                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10828                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10829                            }
10830                            if (outStack != null) {
10831                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10832                            }
10833                        }
10834                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10835                            outStack.append("(");
10836                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10837                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10838                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10839                                    outStack.append(":");
10840                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10841                                }
10842                            }
10843                            outStack.append(")");
10844                        }
10845                    }
10846                }
10847            }
10848
10849            if (!brief && !oomOnly) {
10850                pw.println();
10851                pw.println("Total PSS by process:");
10852                dumpMemItems(pw, "  ", procMems, true);
10853                pw.println();
10854            }
10855            pw.println("Total PSS by OOM adjustment:");
10856            dumpMemItems(pw, "  ", oomMems, false);
10857            if (!oomOnly) {
10858                PrintWriter out = categoryPw != null ? categoryPw : pw;
10859                out.println();
10860                out.println("Total PSS by category:");
10861                dumpMemItems(out, "  ", catMems, true);
10862            }
10863            pw.println();
10864            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10865            final int[] SINGLE_LONG_FORMAT = new int[] {
10866                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10867            };
10868            long[] longOut = new long[1];
10869            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10870                    SINGLE_LONG_FORMAT, null, longOut, null);
10871            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10872            longOut[0] = 0;
10873            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10874                    SINGLE_LONG_FORMAT, null, longOut, null);
10875            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10876            longOut[0] = 0;
10877            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10878                    SINGLE_LONG_FORMAT, null, longOut, null);
10879            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10880            longOut[0] = 0;
10881            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10882                    SINGLE_LONG_FORMAT, null, longOut, null);
10883            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10884            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10885                    pw.print(shared); pw.println(" kB");
10886            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10887                    pw.print(voltile); pw.println(" kB volatile");
10888        }
10889    }
10890
10891    /**
10892     * Searches array of arguments for the specified string
10893     * @param args array of argument strings
10894     * @param value value to search for
10895     * @return true if the value is contained in the array
10896     */
10897    private static boolean scanArgs(String[] args, String value) {
10898        if (args != null) {
10899            for (String arg : args) {
10900                if (value.equals(arg)) {
10901                    return true;
10902                }
10903            }
10904        }
10905        return false;
10906    }
10907
10908    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10909            ContentProviderRecord cpr, boolean always) {
10910        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10911
10912        if (!inLaunching || always) {
10913            synchronized (cpr) {
10914                cpr.launchingApp = null;
10915                cpr.notifyAll();
10916            }
10917            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10918            String names[] = cpr.info.authority.split(";");
10919            for (int j = 0; j < names.length; j++) {
10920                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10921            }
10922        }
10923
10924        for (int i=0; i<cpr.connections.size(); i++) {
10925            ContentProviderConnection conn = cpr.connections.get(i);
10926            if (conn.waiting) {
10927                // If this connection is waiting for the provider, then we don't
10928                // need to mess with its process unless we are always removing
10929                // or for some reason the provider is not currently launching.
10930                if (inLaunching && !always) {
10931                    continue;
10932                }
10933            }
10934            ProcessRecord capp = conn.client;
10935            conn.dead = true;
10936            if (conn.stableCount > 0) {
10937                if (!capp.persistent && capp.thread != null
10938                        && capp.pid != 0
10939                        && capp.pid != MY_PID) {
10940                    Slog.i(TAG, "Kill " + capp.processName
10941                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10942                            + " in dying process " + (proc != null ? proc.processName : "??"));
10943                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10944                            capp.processName, capp.setAdj, "dying provider "
10945                                    + cpr.name.toShortString());
10946                    Process.killProcessQuiet(capp.pid);
10947                }
10948            } else if (capp.thread != null && conn.provider.provider != null) {
10949                try {
10950                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10951                } catch (RemoteException e) {
10952                }
10953                // In the protocol here, we don't expect the client to correctly
10954                // clean up this connection, we'll just remove it.
10955                cpr.connections.remove(i);
10956                conn.client.conProviders.remove(conn);
10957            }
10958        }
10959
10960        if (inLaunching && always) {
10961            mLaunchingProviders.remove(cpr);
10962        }
10963        return inLaunching;
10964    }
10965
10966    /**
10967     * Main code for cleaning up a process when it has gone away.  This is
10968     * called both as a result of the process dying, or directly when stopping
10969     * a process when running in single process mode.
10970     */
10971    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10972            boolean restarting, boolean allowRestart, int index) {
10973        if (index >= 0) {
10974            mLruProcesses.remove(index);
10975        }
10976
10977        mProcessesToGc.remove(app);
10978
10979        // Dismiss any open dialogs.
10980        if (app.crashDialog != null && !app.forceCrashReport) {
10981            app.crashDialog.dismiss();
10982            app.crashDialog = null;
10983        }
10984        if (app.anrDialog != null) {
10985            app.anrDialog.dismiss();
10986            app.anrDialog = null;
10987        }
10988        if (app.waitDialog != null) {
10989            app.waitDialog.dismiss();
10990            app.waitDialog = null;
10991        }
10992
10993        app.crashing = false;
10994        app.notResponding = false;
10995
10996        app.resetPackageList();
10997        app.unlinkDeathRecipient();
10998        app.thread = null;
10999        app.forcingToForeground = null;
11000        app.foregroundServices = false;
11001        app.foregroundActivities = false;
11002        app.hasShownUi = false;
11003        app.hasAboveClient = false;
11004
11005        mServices.killServicesLocked(app, allowRestart);
11006
11007        boolean restart = false;
11008
11009        // Remove published content providers.
11010        if (!app.pubProviders.isEmpty()) {
11011            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
11012            while (it.hasNext()) {
11013                ContentProviderRecord cpr = it.next();
11014
11015                final boolean always = app.bad || !allowRestart;
11016                if (removeDyingProviderLocked(app, cpr, always) || always) {
11017                    // We left the provider in the launching list, need to
11018                    // restart it.
11019                    restart = true;
11020                }
11021
11022                cpr.provider = null;
11023                cpr.proc = null;
11024            }
11025            app.pubProviders.clear();
11026        }
11027
11028        // Take care of any launching providers waiting for this process.
11029        if (checkAppInLaunchingProvidersLocked(app, false)) {
11030            restart = true;
11031        }
11032
11033        // Unregister from connected content providers.
11034        if (!app.conProviders.isEmpty()) {
11035            for (int i=0; i<app.conProviders.size(); i++) {
11036                ContentProviderConnection conn = app.conProviders.get(i);
11037                conn.provider.connections.remove(conn);
11038            }
11039            app.conProviders.clear();
11040        }
11041
11042        // At this point there may be remaining entries in mLaunchingProviders
11043        // where we were the only one waiting, so they are no longer of use.
11044        // Look for these and clean up if found.
11045        // XXX Commented out for now.  Trying to figure out a way to reproduce
11046        // the actual situation to identify what is actually going on.
11047        if (false) {
11048            for (int i=0; i<mLaunchingProviders.size(); i++) {
11049                ContentProviderRecord cpr = (ContentProviderRecord)
11050                        mLaunchingProviders.get(i);
11051                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
11052                    synchronized (cpr) {
11053                        cpr.launchingApp = null;
11054                        cpr.notifyAll();
11055                    }
11056                }
11057            }
11058        }
11059
11060        skipCurrentReceiverLocked(app);
11061
11062        // Unregister any receivers.
11063        if (app.receivers.size() > 0) {
11064            Iterator<ReceiverList> it = app.receivers.iterator();
11065            while (it.hasNext()) {
11066                removeReceiverLocked(it.next());
11067            }
11068            app.receivers.clear();
11069        }
11070
11071        // If the app is undergoing backup, tell the backup manager about it
11072        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
11073            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
11074                    + mBackupTarget.appInfo + " died during backup");
11075            try {
11076                IBackupManager bm = IBackupManager.Stub.asInterface(
11077                        ServiceManager.getService(Context.BACKUP_SERVICE));
11078                bm.agentDisconnected(app.info.packageName);
11079            } catch (RemoteException e) {
11080                // can't happen; backup manager is local
11081            }
11082        }
11083
11084        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
11085            ProcessChangeItem item = mPendingProcessChanges.get(i);
11086            if (item.pid == app.pid) {
11087                mPendingProcessChanges.remove(i);
11088                mAvailProcessChanges.add(item);
11089            }
11090        }
11091        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
11092
11093        // If the caller is restarting this app, then leave it in its
11094        // current lists and let the caller take care of it.
11095        if (restarting) {
11096            return;
11097        }
11098
11099        if (!app.persistent || app.isolated) {
11100            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
11101                    "Removing non-persistent process during cleanup: " + app);
11102            mProcessNames.remove(app.processName, app.uid);
11103            mIsolatedProcesses.remove(app.uid);
11104            if (mHeavyWeightProcess == app) {
11105                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
11106                        mHeavyWeightProcess.userId, 0));
11107                mHeavyWeightProcess = null;
11108            }
11109        } else if (!app.removed) {
11110            // This app is persistent, so we need to keep its record around.
11111            // If it is not already on the pending app list, add it there
11112            // and start a new process for it.
11113            if (mPersistentStartingProcesses.indexOf(app) < 0) {
11114                mPersistentStartingProcesses.add(app);
11115                restart = true;
11116            }
11117        }
11118        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
11119                "Clean-up removing on hold: " + app);
11120        mProcessesOnHold.remove(app);
11121
11122        if (app == mHomeProcess) {
11123            mHomeProcess = null;
11124        }
11125        if (app == mPreviousProcess) {
11126            mPreviousProcess = null;
11127        }
11128
11129        if (restart && !app.isolated) {
11130            // We have components that still need to be running in the
11131            // process, so re-launch it.
11132            mProcessNames.put(app.processName, app.uid, app);
11133            startProcessLocked(app, "restart", app.processName);
11134        } else if (app.pid > 0 && app.pid != MY_PID) {
11135            // Goodbye!
11136            synchronized (mPidsSelfLocked) {
11137                mPidsSelfLocked.remove(app.pid);
11138                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11139            }
11140            app.setPid(0);
11141        }
11142    }
11143
11144    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11145        // Look through the content providers we are waiting to have launched,
11146        // and if any run in this process then either schedule a restart of
11147        // the process or kill the client waiting for it if this process has
11148        // gone bad.
11149        int NL = mLaunchingProviders.size();
11150        boolean restart = false;
11151        for (int i=0; i<NL; i++) {
11152            ContentProviderRecord cpr = mLaunchingProviders.get(i);
11153            if (cpr.launchingApp == app) {
11154                if (!alwaysBad && !app.bad) {
11155                    restart = true;
11156                } else {
11157                    removeDyingProviderLocked(app, cpr, true);
11158                    // cpr should have been removed from mLaunchingProviders
11159                    NL = mLaunchingProviders.size();
11160                    i--;
11161                }
11162            }
11163        }
11164        return restart;
11165    }
11166
11167    // =========================================================
11168    // SERVICES
11169    // =========================================================
11170
11171    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11172            int flags) {
11173        enforceNotIsolatedCaller("getServices");
11174        synchronized (this) {
11175            return mServices.getRunningServiceInfoLocked(maxNum, flags);
11176        }
11177    }
11178
11179    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11180        enforceNotIsolatedCaller("getRunningServiceControlPanel");
11181        synchronized (this) {
11182            return mServices.getRunningServiceControlPanelLocked(name);
11183        }
11184    }
11185
11186    public ComponentName startService(IApplicationThread caller, Intent service,
11187            String resolvedType, int userId) {
11188        enforceNotIsolatedCaller("startService");
11189        // Refuse possible leaked file descriptors
11190        if (service != null && service.hasFileDescriptors() == true) {
11191            throw new IllegalArgumentException("File descriptors passed in Intent");
11192        }
11193
11194        if (DEBUG_SERVICE)
11195            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11196        synchronized(this) {
11197            final int callingPid = Binder.getCallingPid();
11198            final int callingUid = Binder.getCallingUid();
11199            checkValidCaller(callingUid, userId);
11200            final long origId = Binder.clearCallingIdentity();
11201            ComponentName res = mServices.startServiceLocked(caller, service,
11202                    resolvedType, callingPid, callingUid, userId);
11203            Binder.restoreCallingIdentity(origId);
11204            return res;
11205        }
11206    }
11207
11208    ComponentName startServiceInPackage(int uid,
11209            Intent service, String resolvedType, int userId) {
11210        synchronized(this) {
11211            if (DEBUG_SERVICE)
11212                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11213            final long origId = Binder.clearCallingIdentity();
11214            ComponentName res = mServices.startServiceLocked(null, service,
11215                    resolvedType, -1, uid, userId);
11216            Binder.restoreCallingIdentity(origId);
11217            return res;
11218        }
11219    }
11220
11221    public int stopService(IApplicationThread caller, Intent service,
11222            String resolvedType, int userId) {
11223        enforceNotIsolatedCaller("stopService");
11224        // Refuse possible leaked file descriptors
11225        if (service != null && service.hasFileDescriptors() == true) {
11226            throw new IllegalArgumentException("File descriptors passed in Intent");
11227        }
11228
11229        checkValidCaller(Binder.getCallingUid(), userId);
11230
11231        synchronized(this) {
11232            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
11233        }
11234    }
11235
11236    public IBinder peekService(Intent service, String resolvedType) {
11237        enforceNotIsolatedCaller("peekService");
11238        // Refuse possible leaked file descriptors
11239        if (service != null && service.hasFileDescriptors() == true) {
11240            throw new IllegalArgumentException("File descriptors passed in Intent");
11241        }
11242        synchronized(this) {
11243            return mServices.peekServiceLocked(service, resolvedType);
11244        }
11245    }
11246
11247    public boolean stopServiceToken(ComponentName className, IBinder token,
11248            int startId) {
11249        synchronized(this) {
11250            return mServices.stopServiceTokenLocked(className, token, startId);
11251        }
11252    }
11253
11254    public void setServiceForeground(ComponentName className, IBinder token,
11255            int id, Notification notification, boolean removeNotification) {
11256        synchronized(this) {
11257            mServices.setServiceForegroundLocked(className, token, id, notification,
11258                    removeNotification);
11259        }
11260    }
11261
11262    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
11263            boolean requireFull, String name, String callerPackage) {
11264        final int callingUserId = UserHandle.getUserId(callingUid);
11265        if (callingUserId != userId) {
11266            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11267                if ((requireFull || checkComponentPermission(
11268                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11269                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
11270                        && checkComponentPermission(
11271                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11272                                callingPid, callingUid, -1, true)
11273                                != PackageManager.PERMISSION_GRANTED) {
11274                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
11275                        // In this case, they would like to just execute as their
11276                        // owner user instead of failing.
11277                        userId = callingUserId;
11278                    } else {
11279                        StringBuilder builder = new StringBuilder(128);
11280                        builder.append("Permission Denial: ");
11281                        builder.append(name);
11282                        if (callerPackage != null) {
11283                            builder.append(" from ");
11284                            builder.append(callerPackage);
11285                        }
11286                        builder.append(" asks to run as user ");
11287                        builder.append(userId);
11288                        builder.append(" but is calling from user ");
11289                        builder.append(UserHandle.getUserId(callingUid));
11290                        builder.append("; this requires ");
11291                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11292                        if (!requireFull) {
11293                            builder.append(" or ");
11294                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11295                        }
11296                        String msg = builder.toString();
11297                        Slog.w(TAG, msg);
11298                        throw new SecurityException(msg);
11299                    }
11300                }
11301            }
11302            if (userId == UserHandle.USER_CURRENT
11303                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
11304                // Note that we may be accessing this outside of a lock...
11305                // shouldn't be a big deal, if this is being called outside
11306                // of a locked context there is intrinsically a race with
11307                // the value the caller will receive and someone else changing it.
11308                userId = mCurrentUserId;
11309            }
11310            if (!allowAll && userId < 0) {
11311                throw new IllegalArgumentException(
11312                        "Call does not support special user #" + userId);
11313            }
11314        }
11315        return userId;
11316    }
11317
11318    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11319            String className, int flags) {
11320        boolean result = false;
11321        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11322            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11323                if (ActivityManager.checkUidPermission(
11324                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11325                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11326                    ComponentName comp = new ComponentName(aInfo.packageName, className);
11327                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
11328                            + " requests FLAG_SINGLE_USER, but app does not hold "
11329                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11330                    Slog.w(TAG, msg);
11331                    throw new SecurityException(msg);
11332                }
11333                result = true;
11334            }
11335        } else if (componentProcessName == aInfo.packageName) {
11336            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11337        } else if ("system".equals(componentProcessName)) {
11338            result = true;
11339        }
11340        if (DEBUG_MU) {
11341            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11342                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11343        }
11344        return result;
11345    }
11346
11347    public int bindService(IApplicationThread caller, IBinder token,
11348            Intent service, String resolvedType,
11349            IServiceConnection connection, int flags, int userId) {
11350        enforceNotIsolatedCaller("bindService");
11351        // Refuse possible leaked file descriptors
11352        if (service != null && service.hasFileDescriptors() == true) {
11353            throw new IllegalArgumentException("File descriptors passed in Intent");
11354        }
11355
11356        synchronized(this) {
11357            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11358                    connection, flags, userId);
11359        }
11360    }
11361
11362    public boolean unbindService(IServiceConnection connection) {
11363        synchronized (this) {
11364            return mServices.unbindServiceLocked(connection);
11365        }
11366    }
11367
11368    public void publishService(IBinder token, Intent intent, IBinder service) {
11369        // Refuse possible leaked file descriptors
11370        if (intent != null && intent.hasFileDescriptors() == true) {
11371            throw new IllegalArgumentException("File descriptors passed in Intent");
11372        }
11373
11374        synchronized(this) {
11375            if (!(token instanceof ServiceRecord)) {
11376                throw new IllegalArgumentException("Invalid service token");
11377            }
11378            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11379        }
11380    }
11381
11382    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11383        // Refuse possible leaked file descriptors
11384        if (intent != null && intent.hasFileDescriptors() == true) {
11385            throw new IllegalArgumentException("File descriptors passed in Intent");
11386        }
11387
11388        synchronized(this) {
11389            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11390        }
11391    }
11392
11393    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11394        synchronized(this) {
11395            if (!(token instanceof ServiceRecord)) {
11396                throw new IllegalArgumentException("Invalid service token");
11397            }
11398            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11399        }
11400    }
11401
11402    // =========================================================
11403    // BACKUP AND RESTORE
11404    // =========================================================
11405
11406    // Cause the target app to be launched if necessary and its backup agent
11407    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11408    // activity manager to announce its creation.
11409    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11410        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11411        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11412
11413        synchronized(this) {
11414            // !!! TODO: currently no check here that we're already bound
11415            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11416            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11417            synchronized (stats) {
11418                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11419            }
11420
11421            // Backup agent is now in use, its package can't be stopped.
11422            try {
11423                AppGlobals.getPackageManager().setPackageStoppedState(
11424                        app.packageName, false, UserHandle.getUserId(app.uid));
11425            } catch (RemoteException e) {
11426            } catch (IllegalArgumentException e) {
11427                Slog.w(TAG, "Failed trying to unstop package "
11428                        + app.packageName + ": " + e);
11429            }
11430
11431            BackupRecord r = new BackupRecord(ss, app, backupMode);
11432            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11433                    ? new ComponentName(app.packageName, app.backupAgentName)
11434                    : new ComponentName("android", "FullBackupAgent");
11435            // startProcessLocked() returns existing proc's record if it's already running
11436            ProcessRecord proc = startProcessLocked(app.processName, app,
11437                    false, 0, "backup", hostingName, false, false);
11438            if (proc == null) {
11439                Slog.e(TAG, "Unable to start backup agent process " + r);
11440                return false;
11441            }
11442
11443            r.app = proc;
11444            mBackupTarget = r;
11445            mBackupAppName = app.packageName;
11446
11447            // Try not to kill the process during backup
11448            updateOomAdjLocked(proc);
11449
11450            // If the process is already attached, schedule the creation of the backup agent now.
11451            // If it is not yet live, this will be done when it attaches to the framework.
11452            if (proc.thread != null) {
11453                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11454                try {
11455                    proc.thread.scheduleCreateBackupAgent(app,
11456                            compatibilityInfoForPackageLocked(app), backupMode);
11457                } catch (RemoteException e) {
11458                    // Will time out on the backup manager side
11459                }
11460            } else {
11461                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11462            }
11463            // Invariants: at this point, the target app process exists and the application
11464            // is either already running or in the process of coming up.  mBackupTarget and
11465            // mBackupAppName describe the app, so that when it binds back to the AM we
11466            // know that it's scheduled for a backup-agent operation.
11467        }
11468
11469        return true;
11470    }
11471
11472    @Override
11473    public void clearPendingBackup() {
11474        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11475        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11476
11477        synchronized (this) {
11478            mBackupTarget = null;
11479            mBackupAppName = null;
11480        }
11481    }
11482
11483    // A backup agent has just come up
11484    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11485        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11486                + " = " + agent);
11487
11488        synchronized(this) {
11489            if (!agentPackageName.equals(mBackupAppName)) {
11490                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11491                return;
11492            }
11493        }
11494
11495        long oldIdent = Binder.clearCallingIdentity();
11496        try {
11497            IBackupManager bm = IBackupManager.Stub.asInterface(
11498                    ServiceManager.getService(Context.BACKUP_SERVICE));
11499            bm.agentConnected(agentPackageName, agent);
11500        } catch (RemoteException e) {
11501            // can't happen; the backup manager service is local
11502        } catch (Exception e) {
11503            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11504            e.printStackTrace();
11505        } finally {
11506            Binder.restoreCallingIdentity(oldIdent);
11507        }
11508    }
11509
11510    // done with this agent
11511    public void unbindBackupAgent(ApplicationInfo appInfo) {
11512        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11513        if (appInfo == null) {
11514            Slog.w(TAG, "unbind backup agent for null app");
11515            return;
11516        }
11517
11518        synchronized(this) {
11519            try {
11520                if (mBackupAppName == null) {
11521                    Slog.w(TAG, "Unbinding backup agent with no active backup");
11522                    return;
11523                }
11524
11525                if (!mBackupAppName.equals(appInfo.packageName)) {
11526                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11527                    return;
11528                }
11529
11530                // Not backing this app up any more; reset its OOM adjustment
11531                final ProcessRecord proc = mBackupTarget.app;
11532                updateOomAdjLocked(proc);
11533
11534                // If the app crashed during backup, 'thread' will be null here
11535                if (proc.thread != null) {
11536                    try {
11537                        proc.thread.scheduleDestroyBackupAgent(appInfo,
11538                                compatibilityInfoForPackageLocked(appInfo));
11539                    } catch (Exception e) {
11540                        Slog.e(TAG, "Exception when unbinding backup agent:");
11541                        e.printStackTrace();
11542                    }
11543                }
11544            } finally {
11545                mBackupTarget = null;
11546                mBackupAppName = null;
11547            }
11548        }
11549    }
11550    // =========================================================
11551    // BROADCASTS
11552    // =========================================================
11553
11554    private final List getStickiesLocked(String action, IntentFilter filter,
11555            List cur, int userId) {
11556        final ContentResolver resolver = mContext.getContentResolver();
11557        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11558        if (stickies == null) {
11559            return cur;
11560        }
11561        final ArrayList<Intent> list = stickies.get(action);
11562        if (list == null) {
11563            return cur;
11564        }
11565        int N = list.size();
11566        for (int i=0; i<N; i++) {
11567            Intent intent = list.get(i);
11568            if (filter.match(resolver, intent, true, TAG) >= 0) {
11569                if (cur == null) {
11570                    cur = new ArrayList<Intent>();
11571                }
11572                cur.add(intent);
11573            }
11574        }
11575        return cur;
11576    }
11577
11578    boolean isPendingBroadcastProcessLocked(int pid) {
11579        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11580                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11581    }
11582
11583    void skipPendingBroadcastLocked(int pid) {
11584            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11585            for (BroadcastQueue queue : mBroadcastQueues) {
11586                queue.skipPendingBroadcastLocked(pid);
11587            }
11588    }
11589
11590    // The app just attached; send any pending broadcasts that it should receive
11591    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11592        boolean didSomething = false;
11593        for (BroadcastQueue queue : mBroadcastQueues) {
11594            didSomething |= queue.sendPendingBroadcastsLocked(app);
11595        }
11596        return didSomething;
11597    }
11598
11599    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11600            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11601        enforceNotIsolatedCaller("registerReceiver");
11602        int callingUid;
11603        int callingPid;
11604        synchronized(this) {
11605            ProcessRecord callerApp = null;
11606            if (caller != null) {
11607                callerApp = getRecordForAppLocked(caller);
11608                if (callerApp == null) {
11609                    throw new SecurityException(
11610                            "Unable to find app for caller " + caller
11611                            + " (pid=" + Binder.getCallingPid()
11612                            + ") when registering receiver " + receiver);
11613                }
11614                if (callerApp.info.uid != Process.SYSTEM_UID &&
11615                        !callerApp.pkgList.contains(callerPackage)) {
11616                    throw new SecurityException("Given caller package " + callerPackage
11617                            + " is not running in process " + callerApp);
11618                }
11619                callingUid = callerApp.info.uid;
11620                callingPid = callerApp.pid;
11621            } else {
11622                callerPackage = null;
11623                callingUid = Binder.getCallingUid();
11624                callingPid = Binder.getCallingPid();
11625            }
11626
11627            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11628                    true, true, "registerReceiver", callerPackage);
11629
11630            List allSticky = null;
11631
11632            // Look for any matching sticky broadcasts...
11633            Iterator actions = filter.actionsIterator();
11634            if (actions != null) {
11635                while (actions.hasNext()) {
11636                    String action = (String)actions.next();
11637                    allSticky = getStickiesLocked(action, filter, allSticky,
11638                            UserHandle.USER_ALL);
11639                    allSticky = getStickiesLocked(action, filter, allSticky,
11640                            UserHandle.getUserId(callingUid));
11641                }
11642            } else {
11643                allSticky = getStickiesLocked(null, filter, allSticky,
11644                        UserHandle.USER_ALL);
11645                allSticky = getStickiesLocked(null, filter, allSticky,
11646                        UserHandle.getUserId(callingUid));
11647            }
11648
11649            // The first sticky in the list is returned directly back to
11650            // the client.
11651            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11652
11653            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11654                    + ": " + sticky);
11655
11656            if (receiver == null) {
11657                return sticky;
11658            }
11659
11660            ReceiverList rl
11661                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11662            if (rl == null) {
11663                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11664                        userId, receiver);
11665                if (rl.app != null) {
11666                    rl.app.receivers.add(rl);
11667                } else {
11668                    try {
11669                        receiver.asBinder().linkToDeath(rl, 0);
11670                    } catch (RemoteException e) {
11671                        return sticky;
11672                    }
11673                    rl.linkedToDeath = true;
11674                }
11675                mRegisteredReceivers.put(receiver.asBinder(), rl);
11676            } else if (rl.uid != callingUid) {
11677                throw new IllegalArgumentException(
11678                        "Receiver requested to register for uid " + callingUid
11679                        + " was previously registered for uid " + rl.uid);
11680            } else if (rl.pid != callingPid) {
11681                throw new IllegalArgumentException(
11682                        "Receiver requested to register for pid " + callingPid
11683                        + " was previously registered for pid " + rl.pid);
11684            } else if (rl.userId != userId) {
11685                throw new IllegalArgumentException(
11686                        "Receiver requested to register for user " + userId
11687                        + " was previously registered for user " + rl.userId);
11688            }
11689            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11690                    permission, callingUid, userId);
11691            rl.add(bf);
11692            if (!bf.debugCheck()) {
11693                Slog.w(TAG, "==> For Dynamic broadast");
11694            }
11695            mReceiverResolver.addFilter(bf);
11696
11697            // Enqueue broadcasts for all existing stickies that match
11698            // this filter.
11699            if (allSticky != null) {
11700                ArrayList receivers = new ArrayList();
11701                receivers.add(bf);
11702
11703                int N = allSticky.size();
11704                for (int i=0; i<N; i++) {
11705                    Intent intent = (Intent)allSticky.get(i);
11706                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11707                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11708                            null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0,
11709                            null, null, false, true, true, -1);
11710                    queue.enqueueParallelBroadcastLocked(r);
11711                    queue.scheduleBroadcastsLocked();
11712                }
11713            }
11714
11715            return sticky;
11716        }
11717    }
11718
11719    public void unregisterReceiver(IIntentReceiver receiver) {
11720        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11721
11722        final long origId = Binder.clearCallingIdentity();
11723        try {
11724            boolean doTrim = false;
11725
11726            synchronized(this) {
11727                ReceiverList rl
11728                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11729                if (rl != null) {
11730                    if (rl.curBroadcast != null) {
11731                        BroadcastRecord r = rl.curBroadcast;
11732                        final boolean doNext = finishReceiverLocked(
11733                                receiver.asBinder(), r.resultCode, r.resultData,
11734                                r.resultExtras, r.resultAbort, true);
11735                        if (doNext) {
11736                            doTrim = true;
11737                            r.queue.processNextBroadcast(false);
11738                        }
11739                    }
11740
11741                    if (rl.app != null) {
11742                        rl.app.receivers.remove(rl);
11743                    }
11744                    removeReceiverLocked(rl);
11745                    if (rl.linkedToDeath) {
11746                        rl.linkedToDeath = false;
11747                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11748                    }
11749                }
11750            }
11751
11752            // If we actually concluded any broadcasts, we might now be able
11753            // to trim the recipients' apps from our working set
11754            if (doTrim) {
11755                trimApplications();
11756                return;
11757            }
11758
11759        } finally {
11760            Binder.restoreCallingIdentity(origId);
11761        }
11762    }
11763
11764    void removeReceiverLocked(ReceiverList rl) {
11765        mRegisteredReceivers.remove(rl.receiver.asBinder());
11766        int N = rl.size();
11767        for (int i=0; i<N; i++) {
11768            mReceiverResolver.removeFilter(rl.get(i));
11769        }
11770    }
11771
11772    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11773        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11774            ProcessRecord r = mLruProcesses.get(i);
11775            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11776                try {
11777                    r.thread.dispatchPackageBroadcast(cmd, packages);
11778                } catch (RemoteException ex) {
11779                }
11780            }
11781        }
11782    }
11783
11784    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11785            int[] users) {
11786        List<ResolveInfo> receivers = null;
11787        try {
11788            HashSet<ComponentName> singleUserReceivers = null;
11789            boolean scannedFirstReceivers = false;
11790            for (int user : users) {
11791                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11792                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11793                if (user != 0 && newReceivers != null) {
11794                    // If this is not the primary user, we need to check for
11795                    // any receivers that should be filtered out.
11796                    for (int i=0; i<newReceivers.size(); i++) {
11797                        ResolveInfo ri = newReceivers.get(i);
11798                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11799                            newReceivers.remove(i);
11800                            i--;
11801                        }
11802                    }
11803                }
11804                if (newReceivers != null && newReceivers.size() == 0) {
11805                    newReceivers = null;
11806                }
11807                if (receivers == null) {
11808                    receivers = newReceivers;
11809                } else if (newReceivers != null) {
11810                    // We need to concatenate the additional receivers
11811                    // found with what we have do far.  This would be easy,
11812                    // but we also need to de-dup any receivers that are
11813                    // singleUser.
11814                    if (!scannedFirstReceivers) {
11815                        // Collect any single user receivers we had already retrieved.
11816                        scannedFirstReceivers = true;
11817                        for (int i=0; i<receivers.size(); i++) {
11818                            ResolveInfo ri = receivers.get(i);
11819                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11820                                ComponentName cn = new ComponentName(
11821                                        ri.activityInfo.packageName, ri.activityInfo.name);
11822                                if (singleUserReceivers == null) {
11823                                    singleUserReceivers = new HashSet<ComponentName>();
11824                                }
11825                                singleUserReceivers.add(cn);
11826                            }
11827                        }
11828                    }
11829                    // Add the new results to the existing results, tracking
11830                    // and de-dupping single user receivers.
11831                    for (int i=0; i<newReceivers.size(); i++) {
11832                        ResolveInfo ri = newReceivers.get(i);
11833                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11834                            ComponentName cn = new ComponentName(
11835                                    ri.activityInfo.packageName, ri.activityInfo.name);
11836                            if (singleUserReceivers == null) {
11837                                singleUserReceivers = new HashSet<ComponentName>();
11838                            }
11839                            if (!singleUserReceivers.contains(cn)) {
11840                                singleUserReceivers.add(cn);
11841                                receivers.add(ri);
11842                            }
11843                        } else {
11844                            receivers.add(ri);
11845                        }
11846                    }
11847                }
11848            }
11849        } catch (RemoteException ex) {
11850            // pm is in same process, this will never happen.
11851        }
11852        return receivers;
11853    }
11854
11855    private final int broadcastIntentLocked(ProcessRecord callerApp,
11856            String callerPackage, Intent intent, String resolvedType,
11857            IIntentReceiver resultTo, int resultCode, String resultData,
11858            Bundle map, String requiredPermission, int appOp,
11859            boolean ordered, boolean sticky, int callingPid, int callingUid,
11860            int userId) {
11861        intent = new Intent(intent);
11862
11863        // By default broadcasts do not go to stopped apps.
11864        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11865
11866        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11867            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11868            + " ordered=" + ordered + " userid=" + userId);
11869        if ((resultTo != null) && !ordered) {
11870            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11871        }
11872
11873        userId = handleIncomingUser(callingPid, callingUid, userId,
11874                true, false, "broadcast", callerPackage);
11875
11876        // Make sure that the user who is receiving this broadcast is started.
11877        // If not, we will just skip it.
11878        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11879            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11880                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11881                Slog.w(TAG, "Skipping broadcast of " + intent
11882                        + ": user " + userId + " is stopped");
11883                return ActivityManager.BROADCAST_SUCCESS;
11884            }
11885        }
11886
11887        /*
11888         * Prevent non-system code (defined here to be non-persistent
11889         * processes) from sending protected broadcasts.
11890         */
11891        int callingAppId = UserHandle.getAppId(callingUid);
11892        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11893            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11894            callingUid == 0) {
11895            // Always okay.
11896        } else if (callerApp == null || !callerApp.persistent) {
11897            try {
11898                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11899                        intent.getAction())) {
11900                    String msg = "Permission Denial: not allowed to send broadcast "
11901                            + intent.getAction() + " from pid="
11902                            + callingPid + ", uid=" + callingUid;
11903                    Slog.w(TAG, msg);
11904                    throw new SecurityException(msg);
11905                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
11906                    // Special case for compatibility: we don't want apps to send this,
11907                    // but historically it has not been protected and apps may be using it
11908                    // to poke their own app widget.  So, instead of making it protected,
11909                    // just limit it to the caller.
11910                    if (callerApp == null) {
11911                        String msg = "Permission Denial: not allowed to send broadcast "
11912                                + intent.getAction() + " from unknown caller.";
11913                        Slog.w(TAG, msg);
11914                        throw new SecurityException(msg);
11915                    } else if (intent.getComponent() != null) {
11916                        // They are good enough to send to an explicit component...  verify
11917                        // it is being sent to the calling app.
11918                        if (!intent.getComponent().getPackageName().equals(
11919                                callerApp.info.packageName)) {
11920                            String msg = "Permission Denial: not allowed to send broadcast "
11921                                    + intent.getAction() + " to "
11922                                    + intent.getComponent().getPackageName() + " from "
11923                                    + callerApp.info.packageName;
11924                            Slog.w(TAG, msg);
11925                            throw new SecurityException(msg);
11926                        }
11927                    } else {
11928                        // Limit broadcast to their own package.
11929                        intent.setPackage(callerApp.info.packageName);
11930                    }
11931                }
11932            } catch (RemoteException e) {
11933                Slog.w(TAG, "Remote exception", e);
11934                return ActivityManager.BROADCAST_SUCCESS;
11935            }
11936        }
11937
11938        // Handle special intents: if this broadcast is from the package
11939        // manager about a package being removed, we need to remove all of
11940        // its activities from the history stack.
11941        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11942                intent.getAction());
11943        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11944                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11945                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11946                || uidRemoved) {
11947            if (checkComponentPermission(
11948                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11949                    callingPid, callingUid, -1, true)
11950                    == PackageManager.PERMISSION_GRANTED) {
11951                if (uidRemoved) {
11952                    final Bundle intentExtras = intent.getExtras();
11953                    final int uid = intentExtras != null
11954                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11955                    if (uid >= 0) {
11956                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11957                        synchronized (bs) {
11958                            bs.removeUidStatsLocked(uid);
11959                        }
11960                        mAppOpsService.uidRemoved(uid);
11961                    }
11962                } else {
11963                    // If resources are unavailable just force stop all
11964                    // those packages and flush the attribute cache as well.
11965                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11966                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11967                        if (list != null && (list.length > 0)) {
11968                            for (String pkg : list) {
11969                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11970                            }
11971                            sendPackageBroadcastLocked(
11972                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11973                        }
11974                    } else {
11975                        Uri data = intent.getData();
11976                        String ssp;
11977                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11978                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11979                                forceStopPackageLocked(ssp,
11980                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11981                                        false, userId);
11982                            }
11983                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11984                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11985                                        new String[] {ssp}, userId);
11986                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
11987                                    mAppOpsService.packageRemoved(
11988                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
11989                                }
11990                            }
11991                        }
11992                    }
11993                }
11994            } else {
11995                String msg = "Permission Denial: " + intent.getAction()
11996                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11997                        + ", uid=" + callingUid + ")"
11998                        + " requires "
11999                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12000                Slog.w(TAG, msg);
12001                throw new SecurityException(msg);
12002            }
12003
12004        // Special case for adding a package: by default turn on compatibility
12005        // mode.
12006        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12007            Uri data = intent.getData();
12008            String ssp;
12009            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12010                mCompatModePackages.handlePackageAddedLocked(ssp,
12011                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12012            }
12013        }
12014
12015        /*
12016         * If this is the time zone changed action, queue up a message that will reset the timezone
12017         * of all currently running processes. This message will get queued up before the broadcast
12018         * happens.
12019         */
12020        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12021            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12022        }
12023
12024        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12025            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12026        }
12027
12028        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12029            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12030            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12031        }
12032
12033        // Add to the sticky list if requested.
12034        if (sticky) {
12035            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12036                    callingPid, callingUid)
12037                    != PackageManager.PERMISSION_GRANTED) {
12038                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12039                        + callingPid + ", uid=" + callingUid
12040                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12041                Slog.w(TAG, msg);
12042                throw new SecurityException(msg);
12043            }
12044            if (requiredPermission != null) {
12045                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12046                        + " and enforce permission " + requiredPermission);
12047                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12048            }
12049            if (intent.getComponent() != null) {
12050                throw new SecurityException(
12051                        "Sticky broadcasts can't target a specific component");
12052            }
12053            // We use userId directly here, since the "all" target is maintained
12054            // as a separate set of sticky broadcasts.
12055            if (userId != UserHandle.USER_ALL) {
12056                // But first, if this is not a broadcast to all users, then
12057                // make sure it doesn't conflict with an existing broadcast to
12058                // all users.
12059                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
12060                        UserHandle.USER_ALL);
12061                if (stickies != null) {
12062                    ArrayList<Intent> list = stickies.get(intent.getAction());
12063                    if (list != null) {
12064                        int N = list.size();
12065                        int i;
12066                        for (i=0; i<N; i++) {
12067                            if (intent.filterEquals(list.get(i))) {
12068                                throw new IllegalArgumentException(
12069                                        "Sticky broadcast " + intent + " for user "
12070                                        + userId + " conflicts with existing global broadcast");
12071                            }
12072                        }
12073                    }
12074                }
12075            }
12076            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12077            if (stickies == null) {
12078                stickies = new HashMap<String, ArrayList<Intent>>();
12079                mStickyBroadcasts.put(userId, stickies);
12080            }
12081            ArrayList<Intent> list = stickies.get(intent.getAction());
12082            if (list == null) {
12083                list = new ArrayList<Intent>();
12084                stickies.put(intent.getAction(), list);
12085            }
12086            int N = list.size();
12087            int i;
12088            for (i=0; i<N; i++) {
12089                if (intent.filterEquals(list.get(i))) {
12090                    // This sticky already exists, replace it.
12091                    list.set(i, new Intent(intent));
12092                    break;
12093                }
12094            }
12095            if (i >= N) {
12096                list.add(new Intent(intent));
12097            }
12098        }
12099
12100        int[] users;
12101        if (userId == UserHandle.USER_ALL) {
12102            // Caller wants broadcast to go to all started users.
12103            users = mStartedUserArray;
12104        } else {
12105            // Caller wants broadcast to go to one specific user.
12106            users = new int[] {userId};
12107        }
12108
12109        // Figure out who all will receive this broadcast.
12110        List receivers = null;
12111        List<BroadcastFilter> registeredReceivers = null;
12112        // Need to resolve the intent to interested receivers...
12113        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12114                 == 0) {
12115            receivers = collectReceiverComponents(intent, resolvedType, users);
12116        }
12117        if (intent.getComponent() == null) {
12118            registeredReceivers = mReceiverResolver.queryIntent(intent,
12119                    resolvedType, false, userId);
12120        }
12121
12122        final boolean replacePending =
12123                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12124
12125        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
12126                + " replacePending=" + replacePending);
12127
12128        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12129        if (!ordered && NR > 0) {
12130            // If we are not serializing this broadcast, then send the
12131            // registered receivers separately so they don't wait for the
12132            // components to be launched.
12133            final BroadcastQueue queue = broadcastQueueForIntent(intent);
12134            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12135                    callerPackage, callingPid, callingUid, requiredPermission, appOp,
12136                    registeredReceivers, resultTo, resultCode, resultData, map,
12137                    ordered, sticky, false, userId);
12138            if (DEBUG_BROADCAST) Slog.v(
12139                    TAG, "Enqueueing parallel broadcast " + r);
12140            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
12141            if (!replaced) {
12142                queue.enqueueParallelBroadcastLocked(r);
12143                queue.scheduleBroadcastsLocked();
12144            }
12145            registeredReceivers = null;
12146            NR = 0;
12147        }
12148
12149        // Merge into one list.
12150        int ir = 0;
12151        if (receivers != null) {
12152            // A special case for PACKAGE_ADDED: do not allow the package
12153            // being added to see this broadcast.  This prevents them from
12154            // using this as a back door to get run as soon as they are
12155            // installed.  Maybe in the future we want to have a special install
12156            // broadcast or such for apps, but we'd like to deliberately make
12157            // this decision.
12158            String skipPackages[] = null;
12159            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12160                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12161                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12162                Uri data = intent.getData();
12163                if (data != null) {
12164                    String pkgName = data.getSchemeSpecificPart();
12165                    if (pkgName != null) {
12166                        skipPackages = new String[] { pkgName };
12167                    }
12168                }
12169            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
12170                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12171            }
12172            if (skipPackages != null && (skipPackages.length > 0)) {
12173                for (String skipPackage : skipPackages) {
12174                    if (skipPackage != null) {
12175                        int NT = receivers.size();
12176                        for (int it=0; it<NT; it++) {
12177                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
12178                            if (curt.activityInfo.packageName.equals(skipPackage)) {
12179                                receivers.remove(it);
12180                                it--;
12181                                NT--;
12182                            }
12183                        }
12184                    }
12185                }
12186            }
12187
12188            int NT = receivers != null ? receivers.size() : 0;
12189            int it = 0;
12190            ResolveInfo curt = null;
12191            BroadcastFilter curr = null;
12192            while (it < NT && ir < NR) {
12193                if (curt == null) {
12194                    curt = (ResolveInfo)receivers.get(it);
12195                }
12196                if (curr == null) {
12197                    curr = registeredReceivers.get(ir);
12198                }
12199                if (curr.getPriority() >= curt.priority) {
12200                    // Insert this broadcast record into the final list.
12201                    receivers.add(it, curr);
12202                    ir++;
12203                    curr = null;
12204                    it++;
12205                    NT++;
12206                } else {
12207                    // Skip to the next ResolveInfo in the final list.
12208                    it++;
12209                    curt = null;
12210                }
12211            }
12212        }
12213        while (ir < NR) {
12214            if (receivers == null) {
12215                receivers = new ArrayList();
12216            }
12217            receivers.add(registeredReceivers.get(ir));
12218            ir++;
12219        }
12220
12221        if ((receivers != null && receivers.size() > 0)
12222                || resultTo != null) {
12223            BroadcastQueue queue = broadcastQueueForIntent(intent);
12224            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12225                    callerPackage, callingPid, callingUid, requiredPermission, appOp,
12226                    receivers, resultTo, resultCode, resultData, map, ordered,
12227                    sticky, false, userId);
12228            if (DEBUG_BROADCAST) Slog.v(
12229                    TAG, "Enqueueing ordered broadcast " + r
12230                    + ": prev had " + queue.mOrderedBroadcasts.size());
12231            if (DEBUG_BROADCAST) {
12232                int seq = r.intent.getIntExtra("seq", -1);
12233                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12234            }
12235            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
12236            if (!replaced) {
12237                queue.enqueueOrderedBroadcastLocked(r);
12238                queue.scheduleBroadcastsLocked();
12239            }
12240        }
12241
12242        return ActivityManager.BROADCAST_SUCCESS;
12243    }
12244
12245    final Intent verifyBroadcastLocked(Intent intent) {
12246        // Refuse possible leaked file descriptors
12247        if (intent != null && intent.hasFileDescriptors() == true) {
12248            throw new IllegalArgumentException("File descriptors passed in Intent");
12249        }
12250
12251        int flags = intent.getFlags();
12252
12253        if (!mProcessesReady) {
12254            // if the caller really truly claims to know what they're doing, go
12255            // ahead and allow the broadcast without launching any receivers
12256            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12257                intent = new Intent(intent);
12258                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12259            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12260                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12261                        + " before boot completion");
12262                throw new IllegalStateException("Cannot broadcast before boot completed");
12263            }
12264        }
12265
12266        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12267            throw new IllegalArgumentException(
12268                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12269        }
12270
12271        return intent;
12272    }
12273
12274    public final int broadcastIntent(IApplicationThread caller,
12275            Intent intent, String resolvedType, IIntentReceiver resultTo,
12276            int resultCode, String resultData, Bundle map,
12277            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
12278        enforceNotIsolatedCaller("broadcastIntent");
12279        synchronized(this) {
12280            intent = verifyBroadcastLocked(intent);
12281
12282            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12283            final int callingPid = Binder.getCallingPid();
12284            final int callingUid = Binder.getCallingUid();
12285            final long origId = Binder.clearCallingIdentity();
12286            int res = broadcastIntentLocked(callerApp,
12287                    callerApp != null ? callerApp.info.packageName : null,
12288                    intent, resolvedType, resultTo,
12289                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
12290                    callingPid, callingUid, userId);
12291            Binder.restoreCallingIdentity(origId);
12292            return res;
12293        }
12294    }
12295
12296    int broadcastIntentInPackage(String packageName, int uid,
12297            Intent intent, String resolvedType, IIntentReceiver resultTo,
12298            int resultCode, String resultData, Bundle map,
12299            String requiredPermission, boolean serialized, boolean sticky, int userId) {
12300        synchronized(this) {
12301            intent = verifyBroadcastLocked(intent);
12302
12303            final long origId = Binder.clearCallingIdentity();
12304            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12305                    resultTo, resultCode, resultData, map, requiredPermission,
12306                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
12307            Binder.restoreCallingIdentity(origId);
12308            return res;
12309        }
12310    }
12311
12312    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
12313        // Refuse possible leaked file descriptors
12314        if (intent != null && intent.hasFileDescriptors() == true) {
12315            throw new IllegalArgumentException("File descriptors passed in Intent");
12316        }
12317
12318        userId = handleIncomingUser(Binder.getCallingPid(),
12319                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12320
12321        synchronized(this) {
12322            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12323                    != PackageManager.PERMISSION_GRANTED) {
12324                String msg = "Permission Denial: unbroadcastIntent() from pid="
12325                        + Binder.getCallingPid()
12326                        + ", uid=" + Binder.getCallingUid()
12327                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12328                Slog.w(TAG, msg);
12329                throw new SecurityException(msg);
12330            }
12331            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12332            if (stickies != null) {
12333                ArrayList<Intent> list = stickies.get(intent.getAction());
12334                if (list != null) {
12335                    int N = list.size();
12336                    int i;
12337                    for (i=0; i<N; i++) {
12338                        if (intent.filterEquals(list.get(i))) {
12339                            list.remove(i);
12340                            break;
12341                        }
12342                    }
12343                    if (list.size() <= 0) {
12344                        stickies.remove(intent.getAction());
12345                    }
12346                }
12347                if (stickies.size() <= 0) {
12348                    mStickyBroadcasts.remove(userId);
12349                }
12350            }
12351        }
12352    }
12353
12354    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12355            String resultData, Bundle resultExtras, boolean resultAbort,
12356            boolean explicit) {
12357        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12358        if (r == null) {
12359            Slog.w(TAG, "finishReceiver called but not found on queue");
12360            return false;
12361        }
12362
12363        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12364                explicit);
12365    }
12366
12367    public void finishReceiver(IBinder who, int resultCode, String resultData,
12368            Bundle resultExtras, boolean resultAbort) {
12369        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12370
12371        // Refuse possible leaked file descriptors
12372        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12373            throw new IllegalArgumentException("File descriptors passed in Bundle");
12374        }
12375
12376        final long origId = Binder.clearCallingIdentity();
12377        try {
12378            boolean doNext = false;
12379            BroadcastRecord r = null;
12380
12381            synchronized(this) {
12382                r = broadcastRecordForReceiverLocked(who);
12383                if (r != null) {
12384                    doNext = r.queue.finishReceiverLocked(r, resultCode,
12385                        resultData, resultExtras, resultAbort, true);
12386                }
12387            }
12388
12389            if (doNext) {
12390                r.queue.processNextBroadcast(false);
12391            }
12392            trimApplications();
12393        } finally {
12394            Binder.restoreCallingIdentity(origId);
12395        }
12396    }
12397
12398    // =========================================================
12399    // INSTRUMENTATION
12400    // =========================================================
12401
12402    public boolean startInstrumentation(ComponentName className,
12403            String profileFile, int flags, Bundle arguments,
12404            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
12405            int userId) {
12406        enforceNotIsolatedCaller("startInstrumentation");
12407        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12408                userId, false, true, "startInstrumentation", null);
12409        // Refuse possible leaked file descriptors
12410        if (arguments != null && arguments.hasFileDescriptors()) {
12411            throw new IllegalArgumentException("File descriptors passed in Bundle");
12412        }
12413
12414        synchronized(this) {
12415            InstrumentationInfo ii = null;
12416            ApplicationInfo ai = null;
12417            try {
12418                ii = mContext.getPackageManager().getInstrumentationInfo(
12419                    className, STOCK_PM_FLAGS);
12420                ai = AppGlobals.getPackageManager().getApplicationInfo(
12421                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12422            } catch (PackageManager.NameNotFoundException e) {
12423            } catch (RemoteException e) {
12424            }
12425            if (ii == null) {
12426                reportStartInstrumentationFailure(watcher, className,
12427                        "Unable to find instrumentation info for: " + className);
12428                return false;
12429            }
12430            if (ai == null) {
12431                reportStartInstrumentationFailure(watcher, className,
12432                        "Unable to find instrumentation target package: " + ii.targetPackage);
12433                return false;
12434            }
12435
12436            int match = mContext.getPackageManager().checkSignatures(
12437                    ii.targetPackage, ii.packageName);
12438            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12439                String msg = "Permission Denial: starting instrumentation "
12440                        + className + " from pid="
12441                        + Binder.getCallingPid()
12442                        + ", uid=" + Binder.getCallingPid()
12443                        + " not allowed because package " + ii.packageName
12444                        + " does not have a signature matching the target "
12445                        + ii.targetPackage;
12446                reportStartInstrumentationFailure(watcher, className, msg);
12447                throw new SecurityException(msg);
12448            }
12449
12450            final long origId = Binder.clearCallingIdentity();
12451            // Instrumentation can kill and relaunch even persistent processes
12452            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12453            ProcessRecord app = addAppLocked(ai, false);
12454            app.instrumentationClass = className;
12455            app.instrumentationInfo = ai;
12456            app.instrumentationProfileFile = profileFile;
12457            app.instrumentationArguments = arguments;
12458            app.instrumentationWatcher = watcher;
12459            app.instrumentationUiAutomationConnection = uiAutomationConnection;
12460            app.instrumentationResultClass = className;
12461            Binder.restoreCallingIdentity(origId);
12462        }
12463
12464        return true;
12465    }
12466
12467    /**
12468     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12469     * error to the logs, but if somebody is watching, send the report there too.  This enables
12470     * the "am" command to report errors with more information.
12471     *
12472     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12473     * @param cn The component name of the instrumentation.
12474     * @param report The error report.
12475     */
12476    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12477            ComponentName cn, String report) {
12478        Slog.w(TAG, report);
12479        try {
12480            if (watcher != null) {
12481                Bundle results = new Bundle();
12482                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12483                results.putString("Error", report);
12484                watcher.instrumentationStatus(cn, -1, results);
12485            }
12486        } catch (RemoteException e) {
12487            Slog.w(TAG, e);
12488        }
12489    }
12490
12491    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12492        if (app.instrumentationWatcher != null) {
12493            try {
12494                // NOTE:  IInstrumentationWatcher *must* be oneway here
12495                app.instrumentationWatcher.instrumentationFinished(
12496                    app.instrumentationClass,
12497                    resultCode,
12498                    results);
12499            } catch (RemoteException e) {
12500            }
12501        }
12502        if (app.instrumentationUiAutomationConnection != null) {
12503            try {
12504                app.instrumentationUiAutomationConnection.shutdown();
12505            } catch (RemoteException re) {
12506                /* ignore */
12507            }
12508            // Only a UiAutomation can set this flag and now that
12509            // it is finished we make sure it is reset to its default.
12510            mUserIsMonkey = false;
12511        }
12512        app.instrumentationWatcher = null;
12513        app.instrumentationUiAutomationConnection = null;
12514        app.instrumentationClass = null;
12515        app.instrumentationInfo = null;
12516        app.instrumentationProfileFile = null;
12517        app.instrumentationArguments = null;
12518
12519        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12520    }
12521
12522    public void finishInstrumentation(IApplicationThread target,
12523            int resultCode, Bundle results) {
12524        int userId = UserHandle.getCallingUserId();
12525        // Refuse possible leaked file descriptors
12526        if (results != null && results.hasFileDescriptors()) {
12527            throw new IllegalArgumentException("File descriptors passed in Intent");
12528        }
12529
12530        synchronized(this) {
12531            ProcessRecord app = getRecordForAppLocked(target);
12532            if (app == null) {
12533                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12534                return;
12535            }
12536            final long origId = Binder.clearCallingIdentity();
12537            finishInstrumentationLocked(app, resultCode, results);
12538            Binder.restoreCallingIdentity(origId);
12539        }
12540    }
12541
12542    // =========================================================
12543    // CONFIGURATION
12544    // =========================================================
12545
12546    public ConfigurationInfo getDeviceConfigurationInfo() {
12547        ConfigurationInfo config = new ConfigurationInfo();
12548        synchronized (this) {
12549            config.reqTouchScreen = mConfiguration.touchscreen;
12550            config.reqKeyboardType = mConfiguration.keyboard;
12551            config.reqNavigation = mConfiguration.navigation;
12552            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12553                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12554                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12555            }
12556            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12557                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12558                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12559            }
12560            config.reqGlEsVersion = GL_ES_VERSION;
12561        }
12562        return config;
12563    }
12564
12565    public Configuration getConfiguration() {
12566        Configuration ci;
12567        synchronized(this) {
12568            ci = new Configuration(mConfiguration);
12569        }
12570        return ci;
12571    }
12572
12573    public void updatePersistentConfiguration(Configuration values) {
12574        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12575                "updateConfiguration()");
12576        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12577                "updateConfiguration()");
12578        if (values == null) {
12579            throw new NullPointerException("Configuration must not be null");
12580        }
12581
12582        synchronized(this) {
12583            final long origId = Binder.clearCallingIdentity();
12584            updateConfigurationLocked(values, null, true, false);
12585            Binder.restoreCallingIdentity(origId);
12586        }
12587    }
12588
12589    public void updateConfiguration(Configuration values) {
12590        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12591                "updateConfiguration()");
12592
12593        synchronized(this) {
12594            if (values == null && mWindowManager != null) {
12595                // sentinel: fetch the current configuration from the window manager
12596                values = mWindowManager.computeNewConfiguration();
12597            }
12598
12599            if (mWindowManager != null) {
12600                mProcessList.applyDisplaySize(mWindowManager);
12601            }
12602
12603            final long origId = Binder.clearCallingIdentity();
12604            if (values != null) {
12605                Settings.System.clearConfiguration(values);
12606            }
12607            updateConfigurationLocked(values, null, false, false);
12608            Binder.restoreCallingIdentity(origId);
12609        }
12610    }
12611
12612    /**
12613     * Do either or both things: (1) change the current configuration, and (2)
12614     * make sure the given activity is running with the (now) current
12615     * configuration.  Returns true if the activity has been left running, or
12616     * false if <var>starting</var> is being destroyed to match the new
12617     * configuration.
12618     * @param persistent TODO
12619     */
12620    boolean updateConfigurationLocked(Configuration values,
12621            ActivityRecord starting, boolean persistent, boolean initLocale) {
12622        // do nothing if we are headless
12623        if (mHeadless) return true;
12624
12625        int changes = 0;
12626
12627        boolean kept = true;
12628
12629        if (values != null) {
12630            Configuration newConfig = new Configuration(mConfiguration);
12631            changes = newConfig.updateFrom(values);
12632            if (changes != 0) {
12633                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12634                    Slog.i(TAG, "Updating configuration to: " + values);
12635                }
12636
12637                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12638
12639                if (values.locale != null && !initLocale) {
12640                    saveLocaleLocked(values.locale,
12641                                     !values.locale.equals(mConfiguration.locale),
12642                                     values.userSetLocale);
12643                }
12644
12645                mConfigurationSeq++;
12646                if (mConfigurationSeq <= 0) {
12647                    mConfigurationSeq = 1;
12648                }
12649                newConfig.seq = mConfigurationSeq;
12650                mConfiguration = newConfig;
12651                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
12652
12653                final Configuration configCopy = new Configuration(mConfiguration);
12654
12655                // TODO: If our config changes, should we auto dismiss any currently
12656                // showing dialogs?
12657                mShowDialogs = shouldShowDialogs(newConfig);
12658
12659                AttributeCache ac = AttributeCache.instance();
12660                if (ac != null) {
12661                    ac.updateConfiguration(configCopy);
12662                }
12663
12664                // Make sure all resources in our process are updated
12665                // right now, so that anyone who is going to retrieve
12666                // resource values after we return will be sure to get
12667                // the new ones.  This is especially important during
12668                // boot, where the first config change needs to guarantee
12669                // all resources have that config before following boot
12670                // code is executed.
12671                mSystemThread.applyConfigurationToResources(configCopy);
12672
12673                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12674                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12675                    msg.obj = new Configuration(configCopy);
12676                    mHandler.sendMessage(msg);
12677                }
12678
12679                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12680                    ProcessRecord app = mLruProcesses.get(i);
12681                    try {
12682                        if (app.thread != null) {
12683                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12684                                    + app.processName + " new config " + mConfiguration);
12685                            app.thread.scheduleConfigurationChanged(configCopy);
12686                        }
12687                    } catch (Exception e) {
12688                    }
12689                }
12690                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12691                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12692                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12693                        | Intent.FLAG_RECEIVER_FOREGROUND);
12694                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12695                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
12696                        Process.SYSTEM_UID, UserHandle.USER_ALL);
12697                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12698                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12699                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12700                    broadcastIntentLocked(null, null, intent,
12701                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12702                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12703                }
12704            }
12705        }
12706
12707        if (changes != 0 && starting == null) {
12708            // If the configuration changed, and the caller is not already
12709            // in the process of starting an activity, then find the top
12710            // activity to check if its configuration needs to change.
12711            starting = mMainStack.topRunningActivityLocked(null);
12712        }
12713
12714        if (starting != null) {
12715            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12716            // And we need to make sure at this point that all other activities
12717            // are made visible with the correct configuration.
12718            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12719        }
12720
12721        if (values != null && mWindowManager != null) {
12722            mWindowManager.setNewConfiguration(mConfiguration);
12723        }
12724
12725        return kept;
12726    }
12727
12728    /**
12729     * Decide based on the configuration whether we should shouw the ANR,
12730     * crash, etc dialogs.  The idea is that if there is no affordnace to
12731     * press the on-screen buttons, we shouldn't show the dialog.
12732     *
12733     * A thought: SystemUI might also want to get told about this, the Power
12734     * dialog / global actions also might want different behaviors.
12735     */
12736    private static final boolean shouldShowDialogs(Configuration config) {
12737        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12738                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12739    }
12740
12741    /**
12742     * Save the locale.  You must be inside a synchronized (this) block.
12743     */
12744    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12745        if(isDiff) {
12746            SystemProperties.set("user.language", l.getLanguage());
12747            SystemProperties.set("user.region", l.getCountry());
12748        }
12749
12750        if(isPersist) {
12751            SystemProperties.set("persist.sys.language", l.getLanguage());
12752            SystemProperties.set("persist.sys.country", l.getCountry());
12753            SystemProperties.set("persist.sys.localevar", l.getVariant());
12754        }
12755    }
12756
12757    @Override
12758    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12759        ActivityRecord srec = ActivityRecord.forToken(token);
12760        return srec != null && srec.task.affinity != null &&
12761                srec.task.affinity.equals(destAffinity);
12762    }
12763
12764    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12765            Intent resultData) {
12766        ComponentName dest = destIntent.getComponent();
12767
12768        synchronized (this) {
12769            ActivityRecord srec = ActivityRecord.forToken(token);
12770            if (srec == null) {
12771                return false;
12772            }
12773            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12774            final int start = history.indexOf(srec);
12775            if (start < 0) {
12776                // Current activity is not in history stack; do nothing.
12777                return false;
12778            }
12779            int finishTo = start - 1;
12780            ActivityRecord parent = null;
12781            boolean foundParentInTask = false;
12782            if (dest != null) {
12783                TaskRecord tr = srec.task;
12784                for (int i = start - 1; i >= 0; i--) {
12785                    ActivityRecord r = history.get(i);
12786                    if (tr != r.task) {
12787                        // Couldn't find parent in the same task; stop at the one above this.
12788                        // (Root of current task; in-app "home" behavior)
12789                        // Always at least finish the current activity.
12790                        finishTo = Math.min(start - 1, i + 1);
12791                        parent = history.get(finishTo);
12792                        break;
12793                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12794                            r.info.name.equals(dest.getClassName())) {
12795                        finishTo = i;
12796                        parent = r;
12797                        foundParentInTask = true;
12798                        break;
12799                    }
12800                }
12801            }
12802
12803            if (mController != null) {
12804                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12805                if (next != null) {
12806                    // ask watcher if this is allowed
12807                    boolean resumeOK = true;
12808                    try {
12809                        resumeOK = mController.activityResuming(next.packageName);
12810                    } catch (RemoteException e) {
12811                        mController = null;
12812                        Watchdog.getInstance().setActivityController(null);
12813                    }
12814
12815                    if (!resumeOK) {
12816                        return false;
12817                    }
12818                }
12819            }
12820            final long origId = Binder.clearCallingIdentity();
12821            for (int i = start; i > finishTo; i--) {
12822                ActivityRecord r = history.get(i);
12823                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12824                        "navigate-up", true);
12825                // Only return the supplied result for the first activity finished
12826                resultCode = Activity.RESULT_CANCELED;
12827                resultData = null;
12828            }
12829
12830            if (parent != null && foundParentInTask) {
12831                final int parentLaunchMode = parent.info.launchMode;
12832                final int destIntentFlags = destIntent.getFlags();
12833                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12834                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12835                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12836                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12837                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12838                } else {
12839                    try {
12840                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12841                                destIntent.getComponent(), 0, srec.userId);
12842                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12843                                null, aInfo, parent.appToken, null,
12844                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
12845                                0, null, true, null);
12846                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12847                    } catch (RemoteException e) {
12848                        foundParentInTask = false;
12849                    }
12850                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12851                            resultData, "navigate-up", true);
12852                }
12853            }
12854            Binder.restoreCallingIdentity(origId);
12855            return foundParentInTask;
12856        }
12857    }
12858
12859    public int getLaunchedFromUid(IBinder activityToken) {
12860        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12861        if (srec == null) {
12862            return -1;
12863        }
12864        return srec.launchedFromUid;
12865    }
12866
12867    public String getLaunchedFromPackage(IBinder activityToken) {
12868        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12869        if (srec == null) {
12870            return null;
12871        }
12872        return srec.launchedFromPackage;
12873    }
12874
12875    // =========================================================
12876    // LIFETIME MANAGEMENT
12877    // =========================================================
12878
12879    // Returns which broadcast queue the app is the current [or imminent] receiver
12880    // on, or 'null' if the app is not an active broadcast recipient.
12881    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12882        BroadcastRecord r = app.curReceiver;
12883        if (r != null) {
12884            return r.queue;
12885        }
12886
12887        // It's not the current receiver, but it might be starting up to become one
12888        synchronized (this) {
12889            for (BroadcastQueue queue : mBroadcastQueues) {
12890                r = queue.mPendingBroadcast;
12891                if (r != null && r.curApp == app) {
12892                    // found it; report which queue it's in
12893                    return queue;
12894                }
12895            }
12896        }
12897
12898        return null;
12899    }
12900
12901    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12902            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12903        if (mAdjSeq == app.adjSeq) {
12904            // This adjustment has already been computed.  If we are calling
12905            // from the top, we may have already computed our adjustment with
12906            // an earlier hidden adjustment that isn't really for us... if
12907            // so, use the new hidden adjustment.
12908            if (!recursed && app.hidden) {
12909                if (app.hasActivities) {
12910                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12911                } else if (app.hasClientActivities) {
12912                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12913                } else {
12914                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12915                }
12916            }
12917            return app.curRawAdj;
12918        }
12919
12920        if (app.thread == null) {
12921            app.adjSeq = mAdjSeq;
12922            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12923            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12924        }
12925
12926        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12927        app.adjSource = null;
12928        app.adjTarget = null;
12929        app.empty = false;
12930        app.hidden = false;
12931        app.hasClientActivities = false;
12932
12933        final int activitiesSize = app.activities.size();
12934
12935        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12936            // The max adjustment doesn't allow this app to be anything
12937            // below foreground, so it is not worth doing work for it.
12938            app.adjType = "fixed";
12939            app.adjSeq = mAdjSeq;
12940            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12941            app.hasActivities = false;
12942            app.foregroundActivities = false;
12943            app.keeping = true;
12944            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12945            // System process can do UI, and when they do we want to have
12946            // them trim their memory after the user leaves the UI.  To
12947            // facilitate this, here we need to determine whether or not it
12948            // is currently showing UI.
12949            app.systemNoUi = true;
12950            if (app == TOP_APP) {
12951                app.systemNoUi = false;
12952                app.hasActivities = true;
12953            } else if (activitiesSize > 0) {
12954                for (int j = 0; j < activitiesSize; j++) {
12955                    final ActivityRecord r = app.activities.get(j);
12956                    if (r.visible) {
12957                        app.systemNoUi = false;
12958                    }
12959                    if (r.app == app) {
12960                        app.hasActivities = true;
12961                    }
12962                }
12963            }
12964            return (app.curAdj=app.maxAdj);
12965        }
12966
12967        app.keeping = false;
12968        app.systemNoUi = false;
12969        app.hasActivities = false;
12970
12971        // Determine the importance of the process, starting with most
12972        // important to least, and assign an appropriate OOM adjustment.
12973        int adj;
12974        int schedGroup;
12975        boolean foregroundActivities = false;
12976        boolean interesting = false;
12977        BroadcastQueue queue;
12978        if (app == TOP_APP) {
12979            // The last app on the list is the foreground app.
12980            adj = ProcessList.FOREGROUND_APP_ADJ;
12981            schedGroup = Process.THREAD_GROUP_DEFAULT;
12982            app.adjType = "top-activity";
12983            foregroundActivities = true;
12984            interesting = true;
12985            app.hasActivities = true;
12986        } else if (app.instrumentationClass != null) {
12987            // Don't want to kill running instrumentation.
12988            adj = ProcessList.FOREGROUND_APP_ADJ;
12989            schedGroup = Process.THREAD_GROUP_DEFAULT;
12990            app.adjType = "instrumentation";
12991            interesting = true;
12992        } else if ((queue = isReceivingBroadcast(app)) != null) {
12993            // An app that is currently receiving a broadcast also
12994            // counts as being in the foreground for OOM killer purposes.
12995            // It's placed in a sched group based on the nature of the
12996            // broadcast as reflected by which queue it's active in.
12997            adj = ProcessList.FOREGROUND_APP_ADJ;
12998            schedGroup = (queue == mFgBroadcastQueue)
12999                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13000            app.adjType = "broadcast";
13001        } else if (app.executingServices.size() > 0) {
13002            // An app that is currently executing a service callback also
13003            // counts as being in the foreground.
13004            adj = ProcessList.FOREGROUND_APP_ADJ;
13005            schedGroup = Process.THREAD_GROUP_DEFAULT;
13006            app.adjType = "exec-service";
13007        } else {
13008            // Assume process is hidden (has activities); we will correct
13009            // later if this is not the case.
13010            adj = hiddenAdj;
13011            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13012            app.hidden = true;
13013            app.adjType = "bg-act";
13014        }
13015
13016        boolean hasStoppingActivities = false;
13017
13018        // Examine all activities if not already foreground.
13019        if (!foregroundActivities && activitiesSize > 0) {
13020            for (int j = 0; j < activitiesSize; j++) {
13021                final ActivityRecord r = app.activities.get(j);
13022                if (r.visible) {
13023                    // App has a visible activity; only upgrade adjustment.
13024                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13025                        adj = ProcessList.VISIBLE_APP_ADJ;
13026                        app.adjType = "visible";
13027                    }
13028                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13029                    app.hidden = false;
13030                    app.hasActivities = true;
13031                    foregroundActivities = true;
13032                    break;
13033                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13034                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13035                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13036                        app.adjType = "pausing";
13037                    }
13038                    app.hidden = false;
13039                    foregroundActivities = true;
13040                } else if (r.state == ActivityState.STOPPING) {
13041                    // We will apply the actual adjustment later, because
13042                    // we want to allow this process to immediately go through
13043                    // any memory trimming that is in effect.
13044                    app.hidden = false;
13045                    foregroundActivities = true;
13046                    hasStoppingActivities = true;
13047                }
13048                if (r.app == app) {
13049                    app.hasActivities = true;
13050                }
13051            }
13052        }
13053
13054        if (adj == hiddenAdj && !app.hasActivities) {
13055            if (app.hasClientActivities) {
13056                adj = clientHiddenAdj;
13057                app.adjType = "bg-client-act";
13058            } else {
13059                // Whoops, this process is completely empty as far as we know
13060                // at this point.
13061                adj = emptyAdj;
13062                app.empty = true;
13063                app.adjType = "bg-empty";
13064            }
13065        }
13066
13067        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13068            if (app.foregroundServices) {
13069                // The user is aware of this app, so make it visible.
13070                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13071                app.hidden = false;
13072                app.adjType = "fg-service";
13073                schedGroup = Process.THREAD_GROUP_DEFAULT;
13074            } else if (app.forcingToForeground != null) {
13075                // The user is aware of this app, so make it visible.
13076                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13077                app.hidden = false;
13078                app.adjType = "force-fg";
13079                app.adjSource = app.forcingToForeground;
13080                schedGroup = Process.THREAD_GROUP_DEFAULT;
13081            }
13082        }
13083
13084        if (app.foregroundServices) {
13085            interesting = true;
13086        }
13087
13088        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13089            // We don't want to kill the current heavy-weight process.
13090            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13091            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13092            app.hidden = false;
13093            app.adjType = "heavy";
13094        }
13095
13096        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13097            // This process is hosting what we currently consider to be the
13098            // home app, so we don't want to let it go into the background.
13099            adj = ProcessList.HOME_APP_ADJ;
13100            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13101            app.hidden = false;
13102            app.adjType = "home";
13103        }
13104
13105        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13106                && app.activities.size() > 0) {
13107            // This was the previous process that showed UI to the user.
13108            // We want to try to keep it around more aggressively, to give
13109            // a good experience around switching between two apps.
13110            adj = ProcessList.PREVIOUS_APP_ADJ;
13111            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13112            app.hidden = false;
13113            app.adjType = "previous";
13114        }
13115
13116        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13117                + " reason=" + app.adjType);
13118
13119        // By default, we use the computed adjustment.  It may be changed if
13120        // there are applications dependent on our services or providers, but
13121        // this gives us a baseline and makes sure we don't get into an
13122        // infinite recursion.
13123        app.adjSeq = mAdjSeq;
13124        app.curRawAdj = app.nonStoppingAdj = adj;
13125
13126        if (mBackupTarget != null && app == mBackupTarget.app) {
13127            // If possible we want to avoid killing apps while they're being backed up
13128            if (adj > ProcessList.BACKUP_APP_ADJ) {
13129                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13130                adj = ProcessList.BACKUP_APP_ADJ;
13131                app.adjType = "backup";
13132                app.hidden = false;
13133            }
13134        }
13135
13136        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13137                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13138            final long now = SystemClock.uptimeMillis();
13139            // This process is more important if the top activity is
13140            // bound to the service.
13141            Iterator<ServiceRecord> jt = app.services.iterator();
13142            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13143                ServiceRecord s = jt.next();
13144                if (s.startRequested) {
13145                    if (app.hasShownUi && app != mHomeProcess) {
13146                        // If this process has shown some UI, let it immediately
13147                        // go to the LRU list because it may be pretty heavy with
13148                        // UI stuff.  We'll tag it with a label just to help
13149                        // debug and understand what is going on.
13150                        if (adj > ProcessList.SERVICE_ADJ) {
13151                            app.adjType = "started-bg-ui-services";
13152                        }
13153                    } else {
13154                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
13155                            // This service has seen some activity within
13156                            // recent memory, so we will keep its process ahead
13157                            // of the background processes.
13158                            if (adj > ProcessList.SERVICE_ADJ) {
13159                                adj = ProcessList.SERVICE_ADJ;
13160                                app.adjType = "started-services";
13161                                app.hidden = false;
13162                            }
13163                        }
13164                        // If we have let the service slide into the background
13165                        // state, still have some text describing what it is doing
13166                        // even though the service no longer has an impact.
13167                        if (adj > ProcessList.SERVICE_ADJ) {
13168                            app.adjType = "started-bg-services";
13169                        }
13170                    }
13171                    // Don't kill this process because it is doing work; it
13172                    // has said it is doing work.
13173                    app.keeping = true;
13174                }
13175                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13176                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13177                    Iterator<ArrayList<ConnectionRecord>> kt
13178                            = s.connections.values().iterator();
13179                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13180                        ArrayList<ConnectionRecord> clist = kt.next();
13181                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
13182                            // XXX should compute this based on the max of
13183                            // all connected clients.
13184                            ConnectionRecord cr = clist.get(i);
13185                            if (cr.binding.client == app) {
13186                                // Binding to ourself is not interesting.
13187                                continue;
13188                            }
13189                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
13190                                ProcessRecord client = cr.binding.client;
13191                                int clientAdj = adj;
13192                                int myHiddenAdj = hiddenAdj;
13193                                if (myHiddenAdj > client.hiddenAdj) {
13194                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13195                                        myHiddenAdj = client.hiddenAdj;
13196                                    } else {
13197                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13198                                    }
13199                                }
13200                                int myClientHiddenAdj = clientHiddenAdj;
13201                                if (myClientHiddenAdj > client.clientHiddenAdj) {
13202                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13203                                        myClientHiddenAdj = client.clientHiddenAdj;
13204                                    } else {
13205                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13206                                    }
13207                                }
13208                                int myEmptyAdj = emptyAdj;
13209                                if (myEmptyAdj > client.emptyAdj) {
13210                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
13211                                        myEmptyAdj = client.emptyAdj;
13212                                    } else {
13213                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
13214                                    }
13215                                }
13216                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13217                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13218                                String adjType = null;
13219                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13220                                    // Not doing bind OOM management, so treat
13221                                    // this guy more like a started service.
13222                                    if (app.hasShownUi && app != mHomeProcess) {
13223                                        // If this process has shown some UI, let it immediately
13224                                        // go to the LRU list because it may be pretty heavy with
13225                                        // UI stuff.  We'll tag it with a label just to help
13226                                        // debug and understand what is going on.
13227                                        if (adj > clientAdj) {
13228                                            adjType = "bound-bg-ui-services";
13229                                        }
13230                                        app.hidden = false;
13231                                        clientAdj = adj;
13232                                    } else {
13233                                        if (now >= (s.lastActivity
13234                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
13235                                            // This service has not seen activity within
13236                                            // recent memory, so allow it to drop to the
13237                                            // LRU list if there is no other reason to keep
13238                                            // it around.  We'll also tag it with a label just
13239                                            // to help debug and undertand what is going on.
13240                                            if (adj > clientAdj) {
13241                                                adjType = "bound-bg-services";
13242                                            }
13243                                            clientAdj = adj;
13244                                        }
13245                                    }
13246                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13247                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
13248                                        // If this connection is keeping the service
13249                                        // created, then we want to try to better follow
13250                                        // its memory management semantics for activities.
13251                                        // That is, if it is sitting in the background
13252                                        // LRU list as a hidden process (with activities),
13253                                        // we don't want the service it is connected to
13254                                        // to go into the empty LRU and quickly get killed,
13255                                        // because I'll we'll do is just end up restarting
13256                                        // the service.
13257                                        app.hasClientActivities |= client.hasActivities;
13258                                    }
13259                                }
13260                                if (adj > clientAdj) {
13261                                    // If this process has recently shown UI, and
13262                                    // the process that is binding to it is less
13263                                    // important than being visible, then we don't
13264                                    // care about the binding as much as we care
13265                                    // about letting this process get into the LRU
13266                                    // list to be killed and restarted if needed for
13267                                    // memory.
13268                                    if (app.hasShownUi && app != mHomeProcess
13269                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13270                                        adjType = "bound-bg-ui-services";
13271                                    } else {
13272                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13273                                                |Context.BIND_IMPORTANT)) != 0) {
13274                                            adj = clientAdj;
13275                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13276                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13277                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13278                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13279                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
13280                                            adj = clientAdj;
13281                                        } else {
13282                                            app.pendingUiClean = true;
13283                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
13284                                                adj = ProcessList.VISIBLE_APP_ADJ;
13285                                            }
13286                                        }
13287                                        if (!client.hidden) {
13288                                            app.hidden = false;
13289                                        }
13290                                        if (client.keeping) {
13291                                            app.keeping = true;
13292                                        }
13293                                        adjType = "service";
13294                                    }
13295                                }
13296                                if (adjType != null) {
13297                                    app.adjType = adjType;
13298                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13299                                            .REASON_SERVICE_IN_USE;
13300                                    app.adjSource = cr.binding.client;
13301                                    app.adjSourceOom = clientAdj;
13302                                    app.adjTarget = s.name;
13303                                }
13304                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13305                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13306                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13307                                    }
13308                                }
13309                            }
13310                            final ActivityRecord a = cr.activity;
13311                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13312                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13313                                        (a.visible || a.state == ActivityState.RESUMED
13314                                         || a.state == ActivityState.PAUSING)) {
13315                                    adj = ProcessList.FOREGROUND_APP_ADJ;
13316                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13317                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13318                                    }
13319                                    app.hidden = false;
13320                                    app.adjType = "service";
13321                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13322                                            .REASON_SERVICE_IN_USE;
13323                                    app.adjSource = a;
13324                                    app.adjSourceOom = adj;
13325                                    app.adjTarget = s.name;
13326                                }
13327                            }
13328                        }
13329                    }
13330                }
13331            }
13332
13333            // Finally, if this process has active services running in it, we
13334            // would like to avoid killing it unless it would prevent the current
13335            // application from running.  By default we put the process in
13336            // with the rest of the background processes; as we scan through
13337            // its services we may bump it up from there.
13338            if (adj > hiddenAdj) {
13339                adj = hiddenAdj;
13340                app.hidden = false;
13341                app.adjType = "bg-services";
13342            }
13343        }
13344
13345        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13346                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13347            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13348            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13349                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13350                ContentProviderRecord cpr = jt.next();
13351                for (int i = cpr.connections.size()-1;
13352                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13353                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13354                        i--) {
13355                    ContentProviderConnection conn = cpr.connections.get(i);
13356                    ProcessRecord client = conn.client;
13357                    if (client == app) {
13358                        // Being our own client is not interesting.
13359                        continue;
13360                    }
13361                    int myHiddenAdj = hiddenAdj;
13362                    if (myHiddenAdj > client.hiddenAdj) {
13363                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13364                            myHiddenAdj = client.hiddenAdj;
13365                        } else {
13366                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13367                        }
13368                    }
13369                    int myClientHiddenAdj = clientHiddenAdj;
13370                    if (myClientHiddenAdj > client.clientHiddenAdj) {
13371                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13372                            myClientHiddenAdj = client.clientHiddenAdj;
13373                        } else {
13374                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13375                        }
13376                    }
13377                    int myEmptyAdj = emptyAdj;
13378                    if (myEmptyAdj > client.emptyAdj) {
13379                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13380                            myEmptyAdj = client.emptyAdj;
13381                        } else {
13382                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13383                        }
13384                    }
13385                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13386                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13387                    if (adj > clientAdj) {
13388                        if (app.hasShownUi && app != mHomeProcess
13389                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13390                            app.adjType = "bg-ui-provider";
13391                        } else {
13392                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13393                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13394                            app.adjType = "provider";
13395                        }
13396                        if (!client.hidden) {
13397                            app.hidden = false;
13398                        }
13399                        if (client.keeping) {
13400                            app.keeping = true;
13401                        }
13402                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13403                                .REASON_PROVIDER_IN_USE;
13404                        app.adjSource = client;
13405                        app.adjSourceOom = clientAdj;
13406                        app.adjTarget = cpr.name;
13407                    }
13408                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13409                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13410                    }
13411                }
13412                // If the provider has external (non-framework) process
13413                // dependencies, ensure that its adjustment is at least
13414                // FOREGROUND_APP_ADJ.
13415                if (cpr.hasExternalProcessHandles()) {
13416                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13417                        adj = ProcessList.FOREGROUND_APP_ADJ;
13418                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13419                        app.hidden = false;
13420                        app.keeping = true;
13421                        app.adjType = "provider";
13422                        app.adjTarget = cpr.name;
13423                    }
13424                }
13425            }
13426        }
13427
13428        if (adj == ProcessList.SERVICE_ADJ) {
13429            if (doingAll) {
13430                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13431                mNewNumServiceProcs++;
13432            }
13433            if (app.serviceb) {
13434                adj = ProcessList.SERVICE_B_ADJ;
13435            }
13436        } else {
13437            app.serviceb = false;
13438        }
13439
13440        app.nonStoppingAdj = adj;
13441
13442        if (hasStoppingActivities) {
13443            // Only upgrade adjustment.
13444            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13445                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13446                app.adjType = "stopping";
13447            }
13448        }
13449
13450        app.curRawAdj = adj;
13451
13452        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13453        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13454        if (adj > app.maxAdj) {
13455            adj = app.maxAdj;
13456            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13457                schedGroup = Process.THREAD_GROUP_DEFAULT;
13458            }
13459        }
13460        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13461            app.keeping = true;
13462        }
13463
13464        if (app.hasAboveClient) {
13465            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13466            // then we need to drop its adjustment to be lower than the service's
13467            // in order to honor the request.  We want to drop it by one adjustment
13468            // level...  but there is special meaning applied to various levels so
13469            // we will skip some of them.
13470            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13471                // System process will not get dropped, ever
13472            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13473                adj = ProcessList.VISIBLE_APP_ADJ;
13474            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13475                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13476            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13477                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13478            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13479                adj++;
13480            }
13481        }
13482
13483        int importance = app.memImportance;
13484        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13485            app.curAdj = adj;
13486            app.curSchedGroup = schedGroup;
13487            if (!interesting) {
13488                // For this reporting, if there is not something explicitly
13489                // interesting in this process then we will push it to the
13490                // background importance.
13491                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13492            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13493                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13494            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13495                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13496            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13497                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13498            } else if (adj >= ProcessList.SERVICE_ADJ) {
13499                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13500            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13501                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13502            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13503                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13504            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13505                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13506            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13507                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13508            } else {
13509                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13510            }
13511        }
13512
13513        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13514        if (foregroundActivities != app.foregroundActivities) {
13515            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13516        }
13517        if (changes != 0) {
13518            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13519            app.memImportance = importance;
13520            app.foregroundActivities = foregroundActivities;
13521            int i = mPendingProcessChanges.size()-1;
13522            ProcessChangeItem item = null;
13523            while (i >= 0) {
13524                item = mPendingProcessChanges.get(i);
13525                if (item.pid == app.pid) {
13526                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13527                    break;
13528                }
13529                i--;
13530            }
13531            if (i < 0) {
13532                // No existing item in pending changes; need a new one.
13533                final int NA = mAvailProcessChanges.size();
13534                if (NA > 0) {
13535                    item = mAvailProcessChanges.remove(NA-1);
13536                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13537                } else {
13538                    item = new ProcessChangeItem();
13539                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13540                }
13541                item.changes = 0;
13542                item.pid = app.pid;
13543                item.uid = app.info.uid;
13544                if (mPendingProcessChanges.size() == 0) {
13545                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13546                            "*** Enqueueing dispatch processes changed!");
13547                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13548                }
13549                mPendingProcessChanges.add(item);
13550            }
13551            item.changes |= changes;
13552            item.importance = importance;
13553            item.foregroundActivities = foregroundActivities;
13554            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13555                    + Integer.toHexString(System.identityHashCode(item))
13556                    + " " + app.toShortString() + ": changes=" + item.changes
13557                    + " importance=" + item.importance
13558                    + " foreground=" + item.foregroundActivities
13559                    + " type=" + app.adjType + " source=" + app.adjSource
13560                    + " target=" + app.adjTarget);
13561        }
13562
13563        return app.curRawAdj;
13564    }
13565
13566    /**
13567     * Ask a given process to GC right now.
13568     */
13569    final void performAppGcLocked(ProcessRecord app) {
13570        try {
13571            app.lastRequestedGc = SystemClock.uptimeMillis();
13572            if (app.thread != null) {
13573                if (app.reportLowMemory) {
13574                    app.reportLowMemory = false;
13575                    app.thread.scheduleLowMemory();
13576                } else {
13577                    app.thread.processInBackground();
13578                }
13579            }
13580        } catch (Exception e) {
13581            // whatever.
13582        }
13583    }
13584
13585    /**
13586     * Returns true if things are idle enough to perform GCs.
13587     */
13588    private final boolean canGcNowLocked() {
13589        boolean processingBroadcasts = false;
13590        for (BroadcastQueue q : mBroadcastQueues) {
13591            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13592                processingBroadcasts = true;
13593            }
13594        }
13595        return !processingBroadcasts
13596                && (mSleeping || (mMainStack.mResumedActivity != null &&
13597                        mMainStack.mResumedActivity.idle));
13598    }
13599
13600    /**
13601     * Perform GCs on all processes that are waiting for it, but only
13602     * if things are idle.
13603     */
13604    final void performAppGcsLocked() {
13605        final int N = mProcessesToGc.size();
13606        if (N <= 0) {
13607            return;
13608        }
13609        if (canGcNowLocked()) {
13610            while (mProcessesToGc.size() > 0) {
13611                ProcessRecord proc = mProcessesToGc.remove(0);
13612                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13613                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13614                            <= SystemClock.uptimeMillis()) {
13615                        // To avoid spamming the system, we will GC processes one
13616                        // at a time, waiting a few seconds between each.
13617                        performAppGcLocked(proc);
13618                        scheduleAppGcsLocked();
13619                        return;
13620                    } else {
13621                        // It hasn't been long enough since we last GCed this
13622                        // process...  put it in the list to wait for its time.
13623                        addProcessToGcListLocked(proc);
13624                        break;
13625                    }
13626                }
13627            }
13628
13629            scheduleAppGcsLocked();
13630        }
13631    }
13632
13633    /**
13634     * If all looks good, perform GCs on all processes waiting for them.
13635     */
13636    final void performAppGcsIfAppropriateLocked() {
13637        if (canGcNowLocked()) {
13638            performAppGcsLocked();
13639            return;
13640        }
13641        // Still not idle, wait some more.
13642        scheduleAppGcsLocked();
13643    }
13644
13645    /**
13646     * Schedule the execution of all pending app GCs.
13647     */
13648    final void scheduleAppGcsLocked() {
13649        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13650
13651        if (mProcessesToGc.size() > 0) {
13652            // Schedule a GC for the time to the next process.
13653            ProcessRecord proc = mProcessesToGc.get(0);
13654            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13655
13656            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13657            long now = SystemClock.uptimeMillis();
13658            if (when < (now+GC_TIMEOUT)) {
13659                when = now + GC_TIMEOUT;
13660            }
13661            mHandler.sendMessageAtTime(msg, when);
13662        }
13663    }
13664
13665    /**
13666     * Add a process to the array of processes waiting to be GCed.  Keeps the
13667     * list in sorted order by the last GC time.  The process can't already be
13668     * on the list.
13669     */
13670    final void addProcessToGcListLocked(ProcessRecord proc) {
13671        boolean added = false;
13672        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13673            if (mProcessesToGc.get(i).lastRequestedGc <
13674                    proc.lastRequestedGc) {
13675                added = true;
13676                mProcessesToGc.add(i+1, proc);
13677                break;
13678            }
13679        }
13680        if (!added) {
13681            mProcessesToGc.add(0, proc);
13682        }
13683    }
13684
13685    /**
13686     * Set up to ask a process to GC itself.  This will either do it
13687     * immediately, or put it on the list of processes to gc the next
13688     * time things are idle.
13689     */
13690    final void scheduleAppGcLocked(ProcessRecord app) {
13691        long now = SystemClock.uptimeMillis();
13692        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13693            return;
13694        }
13695        if (!mProcessesToGc.contains(app)) {
13696            addProcessToGcListLocked(app);
13697            scheduleAppGcsLocked();
13698        }
13699    }
13700
13701    final void checkExcessivePowerUsageLocked(boolean doKills) {
13702        updateCpuStatsNow();
13703
13704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13705        boolean doWakeKills = doKills;
13706        boolean doCpuKills = doKills;
13707        if (mLastPowerCheckRealtime == 0) {
13708            doWakeKills = false;
13709        }
13710        if (mLastPowerCheckUptime == 0) {
13711            doCpuKills = false;
13712        }
13713        if (stats.isScreenOn()) {
13714            doWakeKills = false;
13715        }
13716        final long curRealtime = SystemClock.elapsedRealtime();
13717        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13718        final long curUptime = SystemClock.uptimeMillis();
13719        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13720        mLastPowerCheckRealtime = curRealtime;
13721        mLastPowerCheckUptime = curUptime;
13722        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13723            doWakeKills = false;
13724        }
13725        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13726            doCpuKills = false;
13727        }
13728        int i = mLruProcesses.size();
13729        while (i > 0) {
13730            i--;
13731            ProcessRecord app = mLruProcesses.get(i);
13732            if (!app.keeping) {
13733                long wtime;
13734                synchronized (stats) {
13735                    wtime = stats.getProcessWakeTime(app.info.uid,
13736                            app.pid, curRealtime);
13737                }
13738                long wtimeUsed = wtime - app.lastWakeTime;
13739                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13740                if (DEBUG_POWER) {
13741                    StringBuilder sb = new StringBuilder(128);
13742                    sb.append("Wake for ");
13743                    app.toShortString(sb);
13744                    sb.append(": over ");
13745                    TimeUtils.formatDuration(realtimeSince, sb);
13746                    sb.append(" used ");
13747                    TimeUtils.formatDuration(wtimeUsed, sb);
13748                    sb.append(" (");
13749                    sb.append((wtimeUsed*100)/realtimeSince);
13750                    sb.append("%)");
13751                    Slog.i(TAG, sb.toString());
13752                    sb.setLength(0);
13753                    sb.append("CPU for ");
13754                    app.toShortString(sb);
13755                    sb.append(": over ");
13756                    TimeUtils.formatDuration(uptimeSince, sb);
13757                    sb.append(" used ");
13758                    TimeUtils.formatDuration(cputimeUsed, sb);
13759                    sb.append(" (");
13760                    sb.append((cputimeUsed*100)/uptimeSince);
13761                    sb.append("%)");
13762                    Slog.i(TAG, sb.toString());
13763                }
13764                // If a process has held a wake lock for more
13765                // than 50% of the time during this period,
13766                // that sounds bad.  Kill!
13767                if (doWakeKills && realtimeSince > 0
13768                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13769                    synchronized (stats) {
13770                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13771                                realtimeSince, wtimeUsed);
13772                    }
13773                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13774                            + " (pid " + app.pid + "): held " + wtimeUsed
13775                            + " during " + realtimeSince);
13776                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13777                            app.processName, app.setAdj, "excessive wake lock");
13778                    Process.killProcessQuiet(app.pid);
13779                } else if (doCpuKills && uptimeSince > 0
13780                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13781                    synchronized (stats) {
13782                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13783                                uptimeSince, cputimeUsed);
13784                    }
13785                    Slog.w(TAG, "Excessive CPU in " + app.processName
13786                            + " (pid " + app.pid + "): used " + cputimeUsed
13787                            + " during " + uptimeSince);
13788                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13789                            app.processName, app.setAdj, "excessive cpu");
13790                    Process.killProcessQuiet(app.pid);
13791                } else {
13792                    app.lastWakeTime = wtime;
13793                    app.lastCpuTime = app.curCpuTime;
13794                }
13795            }
13796        }
13797    }
13798
13799    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13800            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13801        app.hiddenAdj = hiddenAdj;
13802        app.clientHiddenAdj = clientHiddenAdj;
13803        app.emptyAdj = emptyAdj;
13804
13805        if (app.thread == null) {
13806            return false;
13807        }
13808
13809        final boolean wasKeeping = app.keeping;
13810
13811        boolean success = true;
13812
13813        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13814
13815        if (app.curRawAdj != app.setRawAdj) {
13816            if (wasKeeping && !app.keeping) {
13817                // This app is no longer something we want to keep.  Note
13818                // its current wake lock time to later know to kill it if
13819                // it is not behaving well.
13820                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13821                synchronized (stats) {
13822                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13823                            app.pid, SystemClock.elapsedRealtime());
13824                }
13825                app.lastCpuTime = app.curCpuTime;
13826            }
13827
13828            app.setRawAdj = app.curRawAdj;
13829        }
13830
13831        if (app.curAdj != app.setAdj) {
13832            if (Process.setOomAdj(app.pid, app.curAdj)) {
13833                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13834                    TAG, "Set " + app.pid + " " + app.processName +
13835                    " adj " + app.curAdj + ": " + app.adjType);
13836                app.setAdj = app.curAdj;
13837            } else {
13838                success = false;
13839                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13840            }
13841        }
13842        if (app.setSchedGroup != app.curSchedGroup) {
13843            app.setSchedGroup = app.curSchedGroup;
13844            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13845                    "Setting process group of " + app.processName
13846                    + " to " + app.curSchedGroup);
13847            if (app.waitingToKill != null &&
13848                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13849                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13850                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13851                        app.processName, app.setAdj, app.waitingToKill);
13852                app.killedBackground = true;
13853                Process.killProcessQuiet(app.pid);
13854                success = false;
13855            } else {
13856                if (true) {
13857                    long oldId = Binder.clearCallingIdentity();
13858                    try {
13859                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13860                    } catch (Exception e) {
13861                        Slog.w(TAG, "Failed setting process group of " + app.pid
13862                                + " to " + app.curSchedGroup);
13863                        e.printStackTrace();
13864                    } finally {
13865                        Binder.restoreCallingIdentity(oldId);
13866                    }
13867                } else {
13868                    if (app.thread != null) {
13869                        try {
13870                            app.thread.setSchedulingGroup(app.curSchedGroup);
13871                        } catch (RemoteException e) {
13872                        }
13873                    }
13874                }
13875            }
13876        }
13877        return success;
13878    }
13879
13880    private final ActivityRecord resumedAppLocked() {
13881        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13882        if (resumedActivity == null || resumedActivity.app == null) {
13883            resumedActivity = mMainStack.mPausingActivity;
13884            if (resumedActivity == null || resumedActivity.app == null) {
13885                resumedActivity = mMainStack.topRunningActivityLocked(null);
13886            }
13887        }
13888        return resumedActivity;
13889    }
13890
13891    final boolean updateOomAdjLocked(ProcessRecord app) {
13892        final ActivityRecord TOP_ACT = resumedAppLocked();
13893        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13894        int curAdj = app.curAdj;
13895        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13896            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13897
13898        mAdjSeq++;
13899
13900        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13901                app.emptyAdj, TOP_APP, false);
13902        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13903            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13904        if (nowHidden != wasHidden) {
13905            // Changed to/from hidden state, so apps after it in the LRU
13906            // list may also be changed.
13907            updateOomAdjLocked();
13908        }
13909        return success;
13910    }
13911
13912    final void updateOomAdjLocked() {
13913        final ActivityRecord TOP_ACT = resumedAppLocked();
13914        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13915        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13916
13917        if (false) {
13918            RuntimeException e = new RuntimeException();
13919            e.fillInStackTrace();
13920            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13921        }
13922
13923        mAdjSeq++;
13924        mNewNumServiceProcs = 0;
13925
13926        final int emptyProcessLimit;
13927        final int hiddenProcessLimit;
13928        if (mProcessLimit <= 0) {
13929            emptyProcessLimit = hiddenProcessLimit = 0;
13930        } else if (mProcessLimit == 1) {
13931            emptyProcessLimit = 1;
13932            hiddenProcessLimit = 0;
13933        } else {
13934            emptyProcessLimit = (mProcessLimit*2)/3;
13935            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13936        }
13937
13938        // Let's determine how many processes we have running vs.
13939        // how many slots we have for background processes; we may want
13940        // to put multiple processes in a slot of there are enough of
13941        // them.
13942        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13943                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13944        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13945        if (numEmptyProcs > hiddenProcessLimit) {
13946            // If there are more empty processes than our limit on hidden
13947            // processes, then use the hidden process limit for the factor.
13948            // This ensures that the really old empty processes get pushed
13949            // down to the bottom, so if we are running low on memory we will
13950            // have a better chance at keeping around more hidden processes
13951            // instead of a gazillion empty processes.
13952            numEmptyProcs = hiddenProcessLimit;
13953        }
13954        int emptyFactor = numEmptyProcs/numSlots;
13955        if (emptyFactor < 1) emptyFactor = 1;
13956        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13957        if (hiddenFactor < 1) hiddenFactor = 1;
13958        int stepHidden = 0;
13959        int stepEmpty = 0;
13960        int numHidden = 0;
13961        int numEmpty = 0;
13962        int numTrimming = 0;
13963
13964        mNumNonHiddenProcs = 0;
13965        mNumHiddenProcs = 0;
13966
13967        // First update the OOM adjustment for each of the
13968        // application processes based on their current state.
13969        int i = mLruProcesses.size();
13970        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13971        int nextHiddenAdj = curHiddenAdj+1;
13972        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13973        int nextEmptyAdj = curEmptyAdj+2;
13974        int curClientHiddenAdj = curEmptyAdj;
13975        while (i > 0) {
13976            i--;
13977            ProcessRecord app = mLruProcesses.get(i);
13978            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13979            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13980            if (!app.killedBackground) {
13981                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13982                    // This process was assigned as a hidden process...  step the
13983                    // hidden level.
13984                    mNumHiddenProcs++;
13985                    if (curHiddenAdj != nextHiddenAdj) {
13986                        stepHidden++;
13987                        if (stepHidden >= hiddenFactor) {
13988                            stepHidden = 0;
13989                            curHiddenAdj = nextHiddenAdj;
13990                            nextHiddenAdj += 2;
13991                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13992                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13993                            }
13994                            if (curClientHiddenAdj <= curHiddenAdj) {
13995                                curClientHiddenAdj = curHiddenAdj + 1;
13996                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13997                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13998                                }
13999                            }
14000                        }
14001                    }
14002                    numHidden++;
14003                    if (numHidden > hiddenProcessLimit) {
14004                        Slog.i(TAG, "No longer want " + app.processName
14005                                + " (pid " + app.pid + "): hidden #" + numHidden);
14006                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14007                                app.processName, app.setAdj, "too many background");
14008                        app.killedBackground = true;
14009                        Process.killProcessQuiet(app.pid);
14010                    }
14011                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
14012                    // This process has a client that has activities.  We will have
14013                    // given it the current hidden adj; here we will just leave it
14014                    // without stepping the hidden adj.
14015                    curClientHiddenAdj++;
14016                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
14017                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
14018                    }
14019                } else {
14020                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
14021                        // This process was assigned as an empty process...  step the
14022                        // empty level.
14023                        if (curEmptyAdj != nextEmptyAdj) {
14024                            stepEmpty++;
14025                            if (stepEmpty >= emptyFactor) {
14026                                stepEmpty = 0;
14027                                curEmptyAdj = nextEmptyAdj;
14028                                nextEmptyAdj += 2;
14029                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
14030                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
14031                                }
14032                            }
14033                        }
14034                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14035                        mNumNonHiddenProcs++;
14036                    }
14037                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14038                            && !app.hasClientActivities) {
14039                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
14040                                && app.lastActivityTime < oldTime) {
14041                            Slog.i(TAG, "No longer want " + app.processName
14042                                    + " (pid " + app.pid + "): empty for "
14043                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
14044                                            / 1000) + "s");
14045                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14046                                    app.processName, app.setAdj, "old background process");
14047                            app.killedBackground = true;
14048                            Process.killProcessQuiet(app.pid);
14049                        } else {
14050                            numEmpty++;
14051                            if (numEmpty > emptyProcessLimit) {
14052                                Slog.i(TAG, "No longer want " + app.processName
14053                                        + " (pid " + app.pid + "): empty #" + numEmpty);
14054                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14055                                        app.processName, app.setAdj, "too many background");
14056                                app.killedBackground = true;
14057                                Process.killProcessQuiet(app.pid);
14058                            }
14059                        }
14060                    }
14061                }
14062                if (app.isolated && app.services.size() <= 0) {
14063                    // If this is an isolated process, and there are no
14064                    // services running in it, then the process is no longer
14065                    // needed.  We agressively kill these because we can by
14066                    // definition not re-use the same process again, and it is
14067                    // good to avoid having whatever code was running in them
14068                    // left sitting around after no longer needed.
14069                    Slog.i(TAG, "Isolated process " + app.processName
14070                            + " (pid " + app.pid + ") no longer needed");
14071                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14072                            app.processName, app.setAdj, "isolated not needed");
14073                    app.killedBackground = true;
14074                    Process.killProcessQuiet(app.pid);
14075                }
14076                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14077                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14078                        && !app.killedBackground) {
14079                    numTrimming++;
14080                }
14081            }
14082        }
14083
14084        mNumServiceProcs = mNewNumServiceProcs;
14085
14086        // Now determine the memory trimming level of background processes.
14087        // Unfortunately we need to start at the back of the list to do this
14088        // properly.  We only do this if the number of background apps we
14089        // are managing to keep around is less than half the maximum we desire;
14090        // if we are keeping a good number around, we'll let them use whatever
14091        // memory they want.
14092        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
14093                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
14094            final int numHiddenAndEmpty = numHidden + numEmpty;
14095            final int N = mLruProcesses.size();
14096            int factor = numTrimming/3;
14097            int minFactor = 2;
14098            if (mHomeProcess != null) minFactor++;
14099            if (mPreviousProcess != null) minFactor++;
14100            if (factor < minFactor) factor = minFactor;
14101            int step = 0;
14102            int fgTrimLevel;
14103            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
14104                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14105            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
14106                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14107            } else {
14108                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14109            }
14110            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14111            for (i=0; i<N; i++) {
14112                ProcessRecord app = mLruProcesses.get(i);
14113                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14114                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14115                        && !app.killedBackground) {
14116                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14117                        try {
14118                            app.thread.scheduleTrimMemory(curLevel);
14119                        } catch (RemoteException e) {
14120                        }
14121                        if (false) {
14122                            // For now we won't do this; our memory trimming seems
14123                            // to be good enough at this point that destroying
14124                            // activities causes more harm than good.
14125                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14126                                    && app != mHomeProcess && app != mPreviousProcess) {
14127                                // Need to do this on its own message because the stack may not
14128                                // be in a consistent state at this point.
14129                                // For these apps we will also finish their activities
14130                                // to help them free memory.
14131                                mMainStack.scheduleDestroyActivities(app, false, "trim");
14132                            }
14133                        }
14134                    }
14135                    app.trimMemoryLevel = curLevel;
14136                    step++;
14137                    if (step >= factor) {
14138                        step = 0;
14139                        switch (curLevel) {
14140                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14141                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14142                                break;
14143                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14144                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14145                                break;
14146                        }
14147                    }
14148                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14149                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14150                            && app.thread != null) {
14151                        try {
14152                            app.thread.scheduleTrimMemory(
14153                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14154                        } catch (RemoteException e) {
14155                        }
14156                    }
14157                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14158                } else {
14159                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14160                            && app.pendingUiClean) {
14161                        // If this application is now in the background and it
14162                        // had done UI, then give it the special trim level to
14163                        // have it free UI resources.
14164                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14165                        if (app.trimMemoryLevel < level && app.thread != null) {
14166                            try {
14167                                app.thread.scheduleTrimMemory(level);
14168                            } catch (RemoteException e) {
14169                            }
14170                        }
14171                        app.pendingUiClean = false;
14172                    }
14173                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14174                        try {
14175                            app.thread.scheduleTrimMemory(fgTrimLevel);
14176                        } catch (RemoteException e) {
14177                        }
14178                    }
14179                    app.trimMemoryLevel = fgTrimLevel;
14180                }
14181            }
14182        } else {
14183            final int N = mLruProcesses.size();
14184            for (i=0; i<N; i++) {
14185                ProcessRecord app = mLruProcesses.get(i);
14186                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14187                        && app.pendingUiClean) {
14188                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14189                            && app.thread != null) {
14190                        try {
14191                            app.thread.scheduleTrimMemory(
14192                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14193                        } catch (RemoteException e) {
14194                        }
14195                    }
14196                    app.pendingUiClean = false;
14197                }
14198                app.trimMemoryLevel = 0;
14199            }
14200        }
14201
14202        if (mAlwaysFinishActivities) {
14203            // Need to do this on its own message because the stack may not
14204            // be in a consistent state at this point.
14205            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14206        }
14207    }
14208
14209    final void trimApplications() {
14210        synchronized (this) {
14211            int i;
14212
14213            // First remove any unused application processes whose package
14214            // has been removed.
14215            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14216                final ProcessRecord app = mRemovedProcesses.get(i);
14217                if (app.activities.size() == 0
14218                        && app.curReceiver == null && app.services.size() == 0) {
14219                    Slog.i(
14220                        TAG, "Exiting empty application process "
14221                        + app.processName + " ("
14222                        + (app.thread != null ? app.thread.asBinder() : null)
14223                        + ")\n");
14224                    if (app.pid > 0 && app.pid != MY_PID) {
14225                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14226                                app.processName, app.setAdj, "empty");
14227                        Process.killProcessQuiet(app.pid);
14228                    } else {
14229                        try {
14230                            app.thread.scheduleExit();
14231                        } catch (Exception e) {
14232                            // Ignore exceptions.
14233                        }
14234                    }
14235                    cleanUpApplicationRecordLocked(app, false, true, -1);
14236                    mRemovedProcesses.remove(i);
14237
14238                    if (app.persistent) {
14239                        if (app.persistent) {
14240                            addAppLocked(app.info, false);
14241                        }
14242                    }
14243                }
14244            }
14245
14246            // Now update the oom adj for all processes.
14247            updateOomAdjLocked();
14248        }
14249    }
14250
14251    /** This method sends the specified signal to each of the persistent apps */
14252    public void signalPersistentProcesses(int sig) throws RemoteException {
14253        if (sig != Process.SIGNAL_USR1) {
14254            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14255        }
14256
14257        synchronized (this) {
14258            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14259                    != PackageManager.PERMISSION_GRANTED) {
14260                throw new SecurityException("Requires permission "
14261                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14262            }
14263
14264            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14265                ProcessRecord r = mLruProcesses.get(i);
14266                if (r.thread != null && r.persistent) {
14267                    Process.sendSignal(r.pid, sig);
14268                }
14269            }
14270        }
14271    }
14272
14273    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14274        if (proc == null || proc == mProfileProc) {
14275            proc = mProfileProc;
14276            path = mProfileFile;
14277            profileType = mProfileType;
14278            clearProfilerLocked();
14279        }
14280        if (proc == null) {
14281            return;
14282        }
14283        try {
14284            proc.thread.profilerControl(false, path, null, profileType);
14285        } catch (RemoteException e) {
14286            throw new IllegalStateException("Process disappeared");
14287        }
14288    }
14289
14290    private void clearProfilerLocked() {
14291        if (mProfileFd != null) {
14292            try {
14293                mProfileFd.close();
14294            } catch (IOException e) {
14295            }
14296        }
14297        mProfileApp = null;
14298        mProfileProc = null;
14299        mProfileFile = null;
14300        mProfileType = 0;
14301        mAutoStopProfiler = false;
14302    }
14303
14304    public boolean profileControl(String process, int userId, boolean start,
14305            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14306
14307        try {
14308            synchronized (this) {
14309                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14310                // its own permission.
14311                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14312                        != PackageManager.PERMISSION_GRANTED) {
14313                    throw new SecurityException("Requires permission "
14314                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14315                }
14316
14317                if (start && fd == null) {
14318                    throw new IllegalArgumentException("null fd");
14319                }
14320
14321                ProcessRecord proc = null;
14322                if (process != null) {
14323                    proc = findProcessLocked(process, userId, "profileControl");
14324                }
14325
14326                if (start && (proc == null || proc.thread == null)) {
14327                    throw new IllegalArgumentException("Unknown process: " + process);
14328                }
14329
14330                if (start) {
14331                    stopProfilerLocked(null, null, 0);
14332                    setProfileApp(proc.info, proc.processName, path, fd, false);
14333                    mProfileProc = proc;
14334                    mProfileType = profileType;
14335                    try {
14336                        fd = fd.dup();
14337                    } catch (IOException e) {
14338                        fd = null;
14339                    }
14340                    proc.thread.profilerControl(start, path, fd, profileType);
14341                    fd = null;
14342                    mProfileFd = null;
14343                } else {
14344                    stopProfilerLocked(proc, path, profileType);
14345                    if (fd != null) {
14346                        try {
14347                            fd.close();
14348                        } catch (IOException e) {
14349                        }
14350                    }
14351                }
14352
14353                return true;
14354            }
14355        } catch (RemoteException e) {
14356            throw new IllegalStateException("Process disappeared");
14357        } finally {
14358            if (fd != null) {
14359                try {
14360                    fd.close();
14361                } catch (IOException e) {
14362                }
14363            }
14364        }
14365    }
14366
14367    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14368        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14369                userId, true, true, callName, null);
14370        ProcessRecord proc = null;
14371        try {
14372            int pid = Integer.parseInt(process);
14373            synchronized (mPidsSelfLocked) {
14374                proc = mPidsSelfLocked.get(pid);
14375            }
14376        } catch (NumberFormatException e) {
14377        }
14378
14379        if (proc == null) {
14380            HashMap<String, SparseArray<ProcessRecord>> all
14381                    = mProcessNames.getMap();
14382            SparseArray<ProcessRecord> procs = all.get(process);
14383            if (procs != null && procs.size() > 0) {
14384                proc = procs.valueAt(0);
14385                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14386                    for (int i=1; i<procs.size(); i++) {
14387                        ProcessRecord thisProc = procs.valueAt(i);
14388                        if (thisProc.userId == userId) {
14389                            proc = thisProc;
14390                            break;
14391                        }
14392                    }
14393                }
14394            }
14395        }
14396
14397        return proc;
14398    }
14399
14400    public boolean dumpHeap(String process, int userId, boolean managed,
14401            String path, ParcelFileDescriptor fd) throws RemoteException {
14402
14403        try {
14404            synchronized (this) {
14405                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14406                // its own permission (same as profileControl).
14407                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14408                        != PackageManager.PERMISSION_GRANTED) {
14409                    throw new SecurityException("Requires permission "
14410                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14411                }
14412
14413                if (fd == null) {
14414                    throw new IllegalArgumentException("null fd");
14415                }
14416
14417                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14418                if (proc == null || proc.thread == null) {
14419                    throw new IllegalArgumentException("Unknown process: " + process);
14420                }
14421
14422                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14423                if (!isDebuggable) {
14424                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14425                        throw new SecurityException("Process not debuggable: " + proc);
14426                    }
14427                }
14428
14429                proc.thread.dumpHeap(managed, path, fd);
14430                fd = null;
14431                return true;
14432            }
14433        } catch (RemoteException e) {
14434            throw new IllegalStateException("Process disappeared");
14435        } finally {
14436            if (fd != null) {
14437                try {
14438                    fd.close();
14439                } catch (IOException e) {
14440                }
14441            }
14442        }
14443    }
14444
14445    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14446    public void monitor() {
14447        synchronized (this) { }
14448    }
14449
14450    void onCoreSettingsChange(Bundle settings) {
14451        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14452            ProcessRecord processRecord = mLruProcesses.get(i);
14453            try {
14454                if (processRecord.thread != null) {
14455                    processRecord.thread.setCoreSettings(settings);
14456                }
14457            } catch (RemoteException re) {
14458                /* ignore */
14459            }
14460        }
14461    }
14462
14463    // Multi-user methods
14464
14465    @Override
14466    public boolean switchUser(final int userId) {
14467        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14468                != PackageManager.PERMISSION_GRANTED) {
14469            String msg = "Permission Denial: switchUser() from pid="
14470                    + Binder.getCallingPid()
14471                    + ", uid=" + Binder.getCallingUid()
14472                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14473            Slog.w(TAG, msg);
14474            throw new SecurityException(msg);
14475        }
14476
14477        final long ident = Binder.clearCallingIdentity();
14478        try {
14479            synchronized (this) {
14480                final int oldUserId = mCurrentUserId;
14481                if (oldUserId == userId) {
14482                    return true;
14483                }
14484
14485                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14486                if (userInfo == null) {
14487                    Slog.w(TAG, "No user info for user #" + userId);
14488                    return false;
14489                }
14490
14491                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14492                        R.anim.screen_user_enter);
14493
14494                boolean needStart = false;
14495
14496                // If the user we are switching to is not currently started, then
14497                // we need to start it now.
14498                if (mStartedUsers.get(userId) == null) {
14499                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14500                    updateStartedUserArrayLocked();
14501                    needStart = true;
14502                }
14503
14504                mCurrentUserId = userId;
14505                mCurrentUserArray = new int[] { userId };
14506                final Integer userIdInt = Integer.valueOf(userId);
14507                mUserLru.remove(userIdInt);
14508                mUserLru.add(userIdInt);
14509
14510                mWindowManager.setCurrentUser(userId);
14511
14512                // Once the internal notion of the active user has switched, we lock the device
14513                // with the option to show the user switcher on the keyguard.
14514                mWindowManager.lockNow(null);
14515
14516                final UserStartedState uss = mStartedUsers.get(userId);
14517
14518                // Make sure user is in the started state.  If it is currently
14519                // stopping, we need to knock that off.
14520                if (uss.mState == UserStartedState.STATE_STOPPING) {
14521                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14522                    // so we can just fairly silently bring the user back from
14523                    // the almost-dead.
14524                    uss.mState = UserStartedState.STATE_RUNNING;
14525                    updateStartedUserArrayLocked();
14526                    needStart = true;
14527                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14528                    // This means ACTION_SHUTDOWN has been sent, so we will
14529                    // need to treat this as a new boot of the user.
14530                    uss.mState = UserStartedState.STATE_BOOTING;
14531                    updateStartedUserArrayLocked();
14532                    needStart = true;
14533                }
14534
14535                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14536                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14537                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14538                        oldUserId, userId, uss));
14539                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14540                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14541                if (needStart) {
14542                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14543                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14544                            | Intent.FLAG_RECEIVER_FOREGROUND);
14545                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14546                    broadcastIntentLocked(null, null, intent,
14547                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14548                            false, false, MY_PID, Process.SYSTEM_UID, userId);
14549                }
14550
14551                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14552                    if (userId != 0) {
14553                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14554                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14555                        broadcastIntentLocked(null, null, intent, null,
14556                                new IIntentReceiver.Stub() {
14557                                    public void performReceive(Intent intent, int resultCode,
14558                                            String data, Bundle extras, boolean ordered,
14559                                            boolean sticky, int sendingUser) {
14560                                        userInitialized(uss, userId);
14561                                    }
14562                                }, 0, null, null, null, AppOpsManager.OP_NONE,
14563                                true, false, MY_PID, Process.SYSTEM_UID,
14564                                userId);
14565                        uss.initializing = true;
14566                    } else {
14567                        getUserManagerLocked().makeInitialized(userInfo.id);
14568                    }
14569                }
14570
14571                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14572                if (!haveActivities) {
14573                    startHomeActivityLocked(userId);
14574                }
14575
14576                EventLogTags.writeAmSwitchUser(userId);
14577                getUserManagerLocked().userForeground(userId);
14578                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14579                if (needStart) {
14580                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14581                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14582                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14583                    broadcastIntentLocked(null, null, intent,
14584                            null, new IIntentReceiver.Stub() {
14585                                @Override
14586                                public void performReceive(Intent intent, int resultCode, String data,
14587                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14588                                        throws RemoteException {
14589                                }
14590                            }, 0, null, null,
14591                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
14592                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14593                }
14594            }
14595        } finally {
14596            Binder.restoreCallingIdentity(ident);
14597        }
14598
14599        return true;
14600    }
14601
14602    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14603        long ident = Binder.clearCallingIdentity();
14604        try {
14605            Intent intent;
14606            if (oldUserId >= 0) {
14607                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14608                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14609                        | Intent.FLAG_RECEIVER_FOREGROUND);
14610                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14611                broadcastIntentLocked(null, null, intent,
14612                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14613                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14614            }
14615            if (newUserId >= 0) {
14616                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14617                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14618                        | Intent.FLAG_RECEIVER_FOREGROUND);
14619                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14620                broadcastIntentLocked(null, null, intent,
14621                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14622                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14623                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14624                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14625                        | Intent.FLAG_RECEIVER_FOREGROUND);
14626                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14627                broadcastIntentLocked(null, null, intent,
14628                        null, null, 0, null, null,
14629                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
14630                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14631            }
14632        } finally {
14633            Binder.restoreCallingIdentity(ident);
14634        }
14635    }
14636
14637    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14638            final int newUserId) {
14639        final int N = mUserSwitchObservers.beginBroadcast();
14640        if (N > 0) {
14641            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14642                int mCount = 0;
14643                @Override
14644                public void sendResult(Bundle data) throws RemoteException {
14645                    synchronized (ActivityManagerService.this) {
14646                        if (mCurUserSwitchCallback == this) {
14647                            mCount++;
14648                            if (mCount == N) {
14649                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14650                            }
14651                        }
14652                    }
14653                }
14654            };
14655            synchronized (this) {
14656                uss.switching = true;
14657                mCurUserSwitchCallback = callback;
14658            }
14659            for (int i=0; i<N; i++) {
14660                try {
14661                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14662                            newUserId, callback);
14663                } catch (RemoteException e) {
14664                }
14665            }
14666        } else {
14667            synchronized (this) {
14668                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14669            }
14670        }
14671        mUserSwitchObservers.finishBroadcast();
14672    }
14673
14674    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14675        synchronized (this) {
14676            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14677            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14678        }
14679    }
14680
14681    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14682        mCurUserSwitchCallback = null;
14683        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14684        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14685                oldUserId, newUserId, uss));
14686    }
14687
14688    void userInitialized(UserStartedState uss, int newUserId) {
14689        completeSwitchAndInitalize(uss, newUserId, true, false);
14690    }
14691
14692    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14693        completeSwitchAndInitalize(uss, newUserId, false, true);
14694    }
14695
14696    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14697            boolean clearInitializing, boolean clearSwitching) {
14698        boolean unfrozen = false;
14699        synchronized (this) {
14700            if (clearInitializing) {
14701                uss.initializing = false;
14702                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14703            }
14704            if (clearSwitching) {
14705                uss.switching = false;
14706            }
14707            if (!uss.switching && !uss.initializing) {
14708                mWindowManager.stopFreezingScreen();
14709                unfrozen = true;
14710            }
14711        }
14712        if (unfrozen) {
14713            final int N = mUserSwitchObservers.beginBroadcast();
14714            for (int i=0; i<N; i++) {
14715                try {
14716                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14717                } catch (RemoteException e) {
14718                }
14719            }
14720            mUserSwitchObservers.finishBroadcast();
14721        }
14722    }
14723
14724    void finishUserSwitch(UserStartedState uss) {
14725        synchronized (this) {
14726            if (uss.mState == UserStartedState.STATE_BOOTING
14727                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14728                uss.mState = UserStartedState.STATE_RUNNING;
14729                final int userId = uss.mHandle.getIdentifier();
14730                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14731                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14732                broadcastIntentLocked(null, null, intent,
14733                        null, null, 0, null, null,
14734                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
14735                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14736            }
14737            int num = mUserLru.size();
14738            int i = 0;
14739            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14740                Integer oldUserId = mUserLru.get(i);
14741                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14742                if (oldUss == null) {
14743                    // Shouldn't happen, but be sane if it does.
14744                    mUserLru.remove(i);
14745                    num--;
14746                    continue;
14747                }
14748                if (oldUss.mState == UserStartedState.STATE_STOPPING
14749                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14750                    // This user is already stopping, doesn't count.
14751                    num--;
14752                    i++;
14753                    continue;
14754                }
14755                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14756                    // Owner and current can't be stopped, but count as running.
14757                    i++;
14758                    continue;
14759                }
14760                // This is a user to be stopped.
14761                stopUserLocked(oldUserId, null);
14762                num--;
14763                i++;
14764            }
14765        }
14766    }
14767
14768    @Override
14769    public int stopUser(final int userId, final IStopUserCallback callback) {
14770        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14771                != PackageManager.PERMISSION_GRANTED) {
14772            String msg = "Permission Denial: switchUser() from pid="
14773                    + Binder.getCallingPid()
14774                    + ", uid=" + Binder.getCallingUid()
14775                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14776            Slog.w(TAG, msg);
14777            throw new SecurityException(msg);
14778        }
14779        if (userId <= 0) {
14780            throw new IllegalArgumentException("Can't stop primary user " + userId);
14781        }
14782        synchronized (this) {
14783            return stopUserLocked(userId, callback);
14784        }
14785    }
14786
14787    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14788        if (mCurrentUserId == userId) {
14789            return ActivityManager.USER_OP_IS_CURRENT;
14790        }
14791
14792        final UserStartedState uss = mStartedUsers.get(userId);
14793        if (uss == null) {
14794            // User is not started, nothing to do...  but we do need to
14795            // callback if requested.
14796            if (callback != null) {
14797                mHandler.post(new Runnable() {
14798                    @Override
14799                    public void run() {
14800                        try {
14801                            callback.userStopped(userId);
14802                        } catch (RemoteException e) {
14803                        }
14804                    }
14805                });
14806            }
14807            return ActivityManager.USER_OP_SUCCESS;
14808        }
14809
14810        if (callback != null) {
14811            uss.mStopCallbacks.add(callback);
14812        }
14813
14814        if (uss.mState != UserStartedState.STATE_STOPPING
14815                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14816            uss.mState = UserStartedState.STATE_STOPPING;
14817            updateStartedUserArrayLocked();
14818
14819            long ident = Binder.clearCallingIdentity();
14820            try {
14821                // We are going to broadcast ACTION_USER_STOPPING and then
14822                // once that is done send a final ACTION_SHUTDOWN and then
14823                // stop the user.
14824                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14825                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14826                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14827                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14828                // This is the result receiver for the final shutdown broadcast.
14829                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14830                    @Override
14831                    public void performReceive(Intent intent, int resultCode, String data,
14832                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14833                        finishUserStop(uss);
14834                    }
14835                };
14836                // This is the result receiver for the initial stopping broadcast.
14837                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14838                    @Override
14839                    public void performReceive(Intent intent, int resultCode, String data,
14840                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14841                        // On to the next.
14842                        synchronized (ActivityManagerService.this) {
14843                            if (uss.mState != UserStartedState.STATE_STOPPING) {
14844                                // Whoops, we are being started back up.  Abort, abort!
14845                                return;
14846                            }
14847                            uss.mState = UserStartedState.STATE_SHUTDOWN;
14848                        }
14849                        broadcastIntentLocked(null, null, shutdownIntent,
14850                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
14851                                true, false, MY_PID, Process.SYSTEM_UID, userId);
14852                    }
14853                };
14854                // Kick things off.
14855                broadcastIntentLocked(null, null, stoppingIntent,
14856                        null, stoppingReceiver, 0, null, null,
14857                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
14858                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14859            } finally {
14860                Binder.restoreCallingIdentity(ident);
14861            }
14862        }
14863
14864        return ActivityManager.USER_OP_SUCCESS;
14865    }
14866
14867    void finishUserStop(UserStartedState uss) {
14868        final int userId = uss.mHandle.getIdentifier();
14869        boolean stopped;
14870        ArrayList<IStopUserCallback> callbacks;
14871        synchronized (this) {
14872            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14873            if (mStartedUsers.get(userId) != uss) {
14874                stopped = false;
14875            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14876                stopped = false;
14877            } else {
14878                stopped = true;
14879                // User can no longer run.
14880                mStartedUsers.remove(userId);
14881                mUserLru.remove(Integer.valueOf(userId));
14882                updateStartedUserArrayLocked();
14883
14884                // Clean up all state and processes associated with the user.
14885                // Kill all the processes for the user.
14886                forceStopUserLocked(userId);
14887            }
14888        }
14889
14890        for (int i=0; i<callbacks.size(); i++) {
14891            try {
14892                if (stopped) callbacks.get(i).userStopped(userId);
14893                else callbacks.get(i).userStopAborted(userId);
14894            } catch (RemoteException e) {
14895            }
14896        }
14897    }
14898
14899    @Override
14900    public UserInfo getCurrentUser() {
14901        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14902                != PackageManager.PERMISSION_GRANTED) && (
14903                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14904                != PackageManager.PERMISSION_GRANTED)) {
14905            String msg = "Permission Denial: getCurrentUser() from pid="
14906                    + Binder.getCallingPid()
14907                    + ", uid=" + Binder.getCallingUid()
14908                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14909            Slog.w(TAG, msg);
14910            throw new SecurityException(msg);
14911        }
14912        synchronized (this) {
14913            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14914        }
14915    }
14916
14917    int getCurrentUserIdLocked() {
14918        return mCurrentUserId;
14919    }
14920
14921    @Override
14922    public boolean isUserRunning(int userId, boolean orStopped) {
14923        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14924                != PackageManager.PERMISSION_GRANTED) {
14925            String msg = "Permission Denial: isUserRunning() from pid="
14926                    + Binder.getCallingPid()
14927                    + ", uid=" + Binder.getCallingUid()
14928                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14929            Slog.w(TAG, msg);
14930            throw new SecurityException(msg);
14931        }
14932        synchronized (this) {
14933            return isUserRunningLocked(userId, orStopped);
14934        }
14935    }
14936
14937    boolean isUserRunningLocked(int userId, boolean orStopped) {
14938        UserStartedState state = mStartedUsers.get(userId);
14939        if (state == null) {
14940            return false;
14941        }
14942        if (orStopped) {
14943            return true;
14944        }
14945        return state.mState != UserStartedState.STATE_STOPPING
14946                && state.mState != UserStartedState.STATE_SHUTDOWN;
14947    }
14948
14949    @Override
14950    public int[] getRunningUserIds() {
14951        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14952                != PackageManager.PERMISSION_GRANTED) {
14953            String msg = "Permission Denial: isUserRunning() from pid="
14954                    + Binder.getCallingPid()
14955                    + ", uid=" + Binder.getCallingUid()
14956                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14957            Slog.w(TAG, msg);
14958            throw new SecurityException(msg);
14959        }
14960        synchronized (this) {
14961            return mStartedUserArray;
14962        }
14963    }
14964
14965    private void updateStartedUserArrayLocked() {
14966        int num = 0;
14967        for (int i=0; i<mStartedUsers.size();  i++) {
14968            UserStartedState uss = mStartedUsers.valueAt(i);
14969            // This list does not include stopping users.
14970            if (uss.mState != UserStartedState.STATE_STOPPING
14971                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14972                num++;
14973            }
14974        }
14975        mStartedUserArray = new int[num];
14976        num = 0;
14977        for (int i=0; i<mStartedUsers.size();  i++) {
14978            UserStartedState uss = mStartedUsers.valueAt(i);
14979            if (uss.mState != UserStartedState.STATE_STOPPING
14980                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14981                mStartedUserArray[num] = mStartedUsers.keyAt(i);
14982                num++;
14983            }
14984        }
14985    }
14986
14987    @Override
14988    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14989        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14990                != PackageManager.PERMISSION_GRANTED) {
14991            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14992                    + Binder.getCallingPid()
14993                    + ", uid=" + Binder.getCallingUid()
14994                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14995            Slog.w(TAG, msg);
14996            throw new SecurityException(msg);
14997        }
14998
14999        mUserSwitchObservers.register(observer);
15000    }
15001
15002    @Override
15003    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
15004        mUserSwitchObservers.unregister(observer);
15005    }
15006
15007    private boolean userExists(int userId) {
15008        if (userId == 0) {
15009            return true;
15010        }
15011        UserManagerService ums = getUserManagerLocked();
15012        return ums != null ? (ums.getUserInfo(userId) != null) : false;
15013    }
15014
15015    int[] getUsersLocked() {
15016        UserManagerService ums = getUserManagerLocked();
15017        return ums != null ? ums.getUserIds() : new int[] { 0 };
15018    }
15019
15020    UserManagerService getUserManagerLocked() {
15021        if (mUserManager == null) {
15022            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
15023            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
15024        }
15025        return mUserManager;
15026    }
15027
15028    private void checkValidCaller(int uid, int userId) {
15029        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15030
15031        throw new SecurityException("Caller uid=" + uid
15032                + " is not privileged to communicate with user=" + userId);
15033    }
15034
15035    private int applyUserId(int uid, int userId) {
15036        return UserHandle.getUid(userId, uid);
15037    }
15038
15039    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
15040        if (info == null) return null;
15041        ApplicationInfo newInfo = new ApplicationInfo(info);
15042        newInfo.uid = applyUserId(info.uid, userId);
15043        newInfo.dataDir = USER_DATA_DIR + userId + "/"
15044                + info.packageName;
15045        return newInfo;
15046    }
15047
15048    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
15049        if (aInfo == null
15050                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
15051            return aInfo;
15052        }
15053
15054        ActivityInfo info = new ActivityInfo(aInfo);
15055        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15056        return info;
15057    }
15058}
15059