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 com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.internal.widget.LockPatternUtils;
25import com.android.server.AttributeCache;
26import com.android.server.IntentResolver;
27import com.android.server.ProcessMap;
28import com.android.server.SystemServer;
29import com.android.server.Watchdog;
30import com.android.server.am.ActivityStack.ActivityState;
31import com.android.server.pm.UserManagerService;
32import com.android.server.wm.WindowManagerService;
33
34import dalvik.system.Zygote;
35
36import android.app.Activity;
37import android.app.ActivityManager;
38import android.app.ActivityManagerNative;
39import android.app.ActivityOptions;
40import android.app.ActivityThread;
41import android.app.AlertDialog;
42import android.app.AppGlobals;
43import android.app.ApplicationErrorReport;
44import android.app.Dialog;
45import android.app.IActivityController;
46import android.app.IApplicationThread;
47import android.app.IInstrumentationWatcher;
48import android.app.INotificationManager;
49import android.app.IProcessObserver;
50import android.app.IServiceConnection;
51import android.app.IStopUserCallback;
52import android.app.IThumbnailReceiver;
53import android.app.IUserSwitchObserver;
54import android.app.Instrumentation;
55import android.app.Notification;
56import android.app.NotificationManager;
57import android.app.PendingIntent;
58import android.app.backup.IBackupManager;
59import android.content.ActivityNotFoundException;
60import android.content.BroadcastReceiver;
61import android.content.ClipData;
62import android.content.ComponentCallbacks2;
63import android.content.ComponentName;
64import android.content.ContentProvider;
65import android.content.ContentResolver;
66import android.content.Context;
67import android.content.DialogInterface;
68import android.content.IContentProvider;
69import android.content.IIntentReceiver;
70import android.content.IIntentSender;
71import android.content.Intent;
72import android.content.IntentFilter;
73import android.content.IntentSender;
74import android.content.pm.ActivityInfo;
75import android.content.pm.ApplicationInfo;
76import android.content.pm.ConfigurationInfo;
77import android.content.pm.IPackageDataObserver;
78import android.content.pm.IPackageManager;
79import android.content.pm.InstrumentationInfo;
80import android.content.pm.PackageInfo;
81import android.content.pm.PackageManager;
82import android.content.pm.UserInfo;
83import android.content.pm.PackageManager.NameNotFoundException;
84import android.content.pm.PathPermission;
85import android.content.pm.ProviderInfo;
86import android.content.pm.ResolveInfo;
87import android.content.pm.ServiceInfo;
88import android.content.res.CompatibilityInfo;
89import android.content.res.Configuration;
90import android.graphics.Bitmap;
91import android.net.Proxy;
92import android.net.ProxyProperties;
93import android.net.Uri;
94import android.os.Binder;
95import android.os.Build;
96import android.os.Bundle;
97import android.os.Debug;
98import android.os.DropBoxManager;
99import android.os.Environment;
100import android.os.FileObserver;
101import android.os.FileUtils;
102import android.os.Handler;
103import android.os.IBinder;
104import android.os.IPermissionController;
105import android.os.IRemoteCallback;
106import android.os.IUserManager;
107import android.os.Looper;
108import android.os.Message;
109import android.os.Parcel;
110import android.os.ParcelFileDescriptor;
111import android.os.Process;
112import android.os.RemoteCallbackList;
113import android.os.RemoteException;
114import android.os.SELinux;
115import android.os.ServiceManager;
116import android.os.StrictMode;
117import android.os.SystemClock;
118import android.os.SystemProperties;
119import android.os.UserHandle;
120import android.provider.Settings;
121import android.text.format.Time;
122import android.util.EventLog;
123import android.util.Log;
124import android.util.Pair;
125import android.util.PrintWriterPrinter;
126import android.util.Slog;
127import android.util.SparseArray;
128import android.util.TimeUtils;
129import android.view.Gravity;
130import android.view.LayoutInflater;
131import android.view.View;
132import android.view.WindowManager;
133import android.view.WindowManagerPolicy;
134
135import java.io.BufferedInputStream;
136import java.io.BufferedOutputStream;
137import java.io.BufferedReader;
138import java.io.DataInputStream;
139import java.io.DataOutputStream;
140import java.io.File;
141import java.io.FileDescriptor;
142import java.io.FileInputStream;
143import java.io.FileNotFoundException;
144import java.io.FileOutputStream;
145import java.io.IOException;
146import java.io.InputStreamReader;
147import java.io.PrintWriter;
148import java.io.StringWriter;
149import java.lang.ref.WeakReference;
150import java.util.ArrayList;
151import java.util.Arrays;
152import java.util.Collections;
153import java.util.Comparator;
154import java.util.HashMap;
155import java.util.HashSet;
156import java.util.Iterator;
157import java.util.List;
158import java.util.Locale;
159import java.util.Map;
160import java.util.Set;
161import java.util.concurrent.atomic.AtomicBoolean;
162import java.util.concurrent.atomic.AtomicLong;
163
164public final class ActivityManagerService extends ActivityManagerNative
165        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
166    private static final String USER_DATA_DIR = "/data/user/";
167    static final String TAG = "ActivityManager";
168    static final String TAG_MU = "ActivityManagerServiceMU";
169    static final boolean DEBUG = false;
170    static final boolean localLOGV = DEBUG;
171    static final boolean DEBUG_SWITCH = localLOGV || false;
172    static final boolean DEBUG_TASKS = localLOGV || false;
173    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
174    static final boolean DEBUG_PAUSE = localLOGV || false;
175    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176    static final boolean DEBUG_TRANSITION = localLOGV || false;
177    static final boolean DEBUG_BROADCAST = localLOGV || false;
178    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
180    static final boolean DEBUG_SERVICE = localLOGV || false;
181    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
182    static final boolean DEBUG_VISBILITY = localLOGV || false;
183    static final boolean DEBUG_PROCESSES = localLOGV || false;
184    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
185    static final boolean DEBUG_CLEANUP = localLOGV || false;
186    static final boolean DEBUG_PROVIDER = localLOGV || false;
187    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
188    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
189    static final boolean DEBUG_RESULTS = localLOGV || false;
190    static final boolean DEBUG_BACKUP = localLOGV || false;
191    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
192    static final boolean DEBUG_POWER = localLOGV || false;
193    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
194    static final boolean DEBUG_MU = localLOGV || false;
195    static final boolean VALIDATE_TOKENS = false;
196    static final boolean SHOW_ACTIVITY_START_TIME = true;
197
198    // Control over CPU and battery monitoring.
199    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
200    static final boolean MONITOR_CPU_USAGE = true;
201    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
202    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
203    static final boolean MONITOR_THREAD_CPU_USAGE = false;
204
205    // The flags that are set for all calls we make to the package manager.
206    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
207
208    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
209
210    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
211
212    // Maximum number of recent tasks that we can remember.
213    static final int MAX_RECENT_TASKS = 20;
214
215    // Amount of time after a call to stopAppSwitches() during which we will
216    // prevent further untrusted switches from happening.
217    static final long APP_SWITCH_DELAY_TIME = 5*1000;
218
219    // How long we wait for a launched process to attach to the activity manager
220    // before we decide it's never going to come up for real.
221    static final int PROC_START_TIMEOUT = 10*1000;
222
223    // How long we wait for a launched process to attach to the activity manager
224    // before we decide it's never going to come up for real, when the process was
225    // started with a wrapper for instrumentation (such as Valgrind) because it
226    // could take much longer than usual.
227    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
228
229    // How long to wait after going idle before forcing apps to GC.
230    static final int GC_TIMEOUT = 5*1000;
231
232    // The minimum amount of time between successive GC requests for a process.
233    static final int GC_MIN_INTERVAL = 60*1000;
234
235    // The rate at which we check for apps using excessive power -- 15 mins.
236    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on wake locks to start killing things.
240    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // The minimum sample duration we will allow before deciding we have
243    // enough data on CPU usage to start killing things.
244    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
245
246    // How long we allow a receiver to run before giving up on it.
247    static final int BROADCAST_FG_TIMEOUT = 10*1000;
248    static final int BROADCAST_BG_TIMEOUT = 60*1000;
249
250    // How long we wait until we timeout on key dispatching.
251    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
252
253    // How long we wait until we timeout on key dispatching during instrumentation.
254    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
255
256    // Amount of time we wait for observers to handle a user switch before
257    // giving up on them and unfreezing the screen.
258    static final int USER_SWITCH_TIMEOUT = 2*1000;
259
260    // Maximum number of users we allow to be running at a time.
261    static final int MAX_RUNNING_USERS = 3;
262
263    static final int MY_PID = Process.myPid();
264
265    static final String[] EMPTY_STRING_ARRAY = new String[0];
266
267    public ActivityStack mMainStack;
268
269    private final boolean mHeadless;
270
271    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
272    // default actuion automatically.  Important for devices without direct input
273    // devices.
274    private boolean mShowDialogs = true;
275
276    /**
277     * Description of a request to start a new activity, which has been held
278     * due to app switches being disabled.
279     */
280    static class PendingActivityLaunch {
281        ActivityRecord r;
282        ActivityRecord sourceRecord;
283        int startFlags;
284    }
285
286    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
287            = new ArrayList<PendingActivityLaunch>();
288
289
290    BroadcastQueue mFgBroadcastQueue;
291    BroadcastQueue mBgBroadcastQueue;
292    // Convenient for easy iteration over the queues. Foreground is first
293    // so that dispatch of foreground broadcasts gets precedence.
294    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
295
296    BroadcastQueue broadcastQueueForIntent(Intent intent) {
297        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
298        if (DEBUG_BACKGROUND_BROADCAST) {
299            Slog.i(TAG, "Broadcast intent " + intent + " on "
300                    + (isFg ? "foreground" : "background")
301                    + " queue");
302        }
303        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
304    }
305
306    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
307        for (BroadcastQueue queue : mBroadcastQueues) {
308            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
309            if (r != null) {
310                return r;
311            }
312        }
313        return null;
314    }
315
316    /**
317     * Activity we have told the window manager to have key focus.
318     */
319    ActivityRecord mFocusedActivity = null;
320    /**
321     * List of intents that were used to start the most recent tasks.
322     */
323    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
324
325    /**
326     * Process management.
327     */
328    final ProcessList mProcessList = new ProcessList();
329
330    /**
331     * All of the applications we currently have running organized by name.
332     * The keys are strings of the application package name (as
333     * returned by the package manager), and the keys are ApplicationRecord
334     * objects.
335     */
336    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
337
338    /**
339     * The currently running isolated processes.
340     */
341    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
342
343    /**
344     * Counter for assigning isolated process uids, to avoid frequently reusing the
345     * same ones.
346     */
347    int mNextIsolatedProcessUid = 0;
348
349    /**
350     * The currently running heavy-weight process, if any.
351     */
352    ProcessRecord mHeavyWeightProcess = null;
353
354    /**
355     * The last time that various processes have crashed.
356     */
357    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
358
359    /**
360     * Set of applications that we consider to be bad, and will reject
361     * incoming broadcasts from (which the user has no control over).
362     * Processes are added to this set when they have crashed twice within
363     * a minimum amount of time; they are removed from it when they are
364     * later restarted (hopefully due to some user action).  The value is the
365     * time it was added to the list.
366     */
367    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
368
369    /**
370     * All of the processes we currently have running organized by pid.
371     * The keys are the pid running the application.
372     *
373     * <p>NOTE: This object is protected by its own lock, NOT the global
374     * activity manager lock!
375     */
376    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
377
378    /**
379     * All of the processes that have been forced to be foreground.  The key
380     * is the pid of the caller who requested it (we hold a death
381     * link on it).
382     */
383    abstract class ForegroundToken implements IBinder.DeathRecipient {
384        int pid;
385        IBinder token;
386    }
387    final SparseArray<ForegroundToken> mForegroundProcesses
388            = new SparseArray<ForegroundToken>();
389
390    /**
391     * List of records for processes that someone had tried to start before the
392     * system was ready.  We don't start them at that point, but ensure they
393     * are started by the time booting is complete.
394     */
395    final ArrayList<ProcessRecord> mProcessesOnHold
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of persistent applications that are in the process
400     * of being started.
401     */
402    final ArrayList<ProcessRecord> mPersistentStartingProcesses
403            = new ArrayList<ProcessRecord>();
404
405    /**
406     * Processes that are being forcibly torn down.
407     */
408    final ArrayList<ProcessRecord> mRemovedProcesses
409            = new ArrayList<ProcessRecord>();
410
411    /**
412     * List of running applications, sorted by recent usage.
413     * The first entry in the list is the least recently used.
414     * It contains ApplicationRecord objects.  This list does NOT include
415     * any persistent application records (since we never want to exit them).
416     */
417    final ArrayList<ProcessRecord> mLruProcesses
418            = new ArrayList<ProcessRecord>();
419
420    /**
421     * List of processes that should gc as soon as things are idle.
422     */
423    final ArrayList<ProcessRecord> mProcessesToGc
424            = new ArrayList<ProcessRecord>();
425
426    /**
427     * This is the process holding what we currently consider to be
428     * the "home" activity.
429     */
430    ProcessRecord mHomeProcess;
431
432    /**
433     * This is the process holding the activity the user last visited that
434     * is in a different process from the one they are currently in.
435     */
436    ProcessRecord mPreviousProcess;
437
438    /**
439     * The time at which the previous process was last visible.
440     */
441    long mPreviousProcessVisibleTime;
442
443    /**
444     * Which uses have been started, so are allowed to run code.
445     */
446    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
447
448    /**
449     * LRU list of history of current users.  Most recently current is at the end.
450     */
451    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
452
453    /**
454     * Constant array of the users that are currently started.
455     */
456    int[] mStartedUserArray = new int[] { 0 };
457
458    /**
459     * Registered observers of the user switching mechanics.
460     */
461    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
462            = new RemoteCallbackList<IUserSwitchObserver>();
463
464    /**
465     * Currently active user switch.
466     */
467    Object mCurUserSwitchCallback;
468
469    /**
470     * Packages that the user has asked to have run in screen size
471     * compatibility mode instead of filling the screen.
472     */
473    final CompatModePackages mCompatModePackages;
474
475    /**
476     * Set of PendingResultRecord objects that are currently active.
477     */
478    final HashSet mPendingResultRecords = new HashSet();
479
480    /**
481     * Set of IntentSenderRecord objects that are currently active.
482     */
483    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
484            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
485
486    /**
487     * Fingerprints (hashCode()) of stack traces that we've
488     * already logged DropBox entries for.  Guarded by itself.  If
489     * something (rogue user app) forces this over
490     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
491     */
492    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
493    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
494
495    /**
496     * Strict Mode background batched logging state.
497     *
498     * The string buffer is guarded by itself, and its lock is also
499     * used to determine if another batched write is already
500     * in-flight.
501     */
502    private final StringBuilder mStrictModeBuffer = new StringBuilder();
503
504    /**
505     * Keeps track of all IIntentReceivers that have been registered for
506     * broadcasts.  Hash keys are the receiver IBinder, hash value is
507     * a ReceiverList.
508     */
509    final HashMap mRegisteredReceivers = new HashMap();
510
511    /**
512     * Resolver for broadcast intents to registered receivers.
513     * Holds BroadcastFilter (subclass of IntentFilter).
514     */
515    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
516            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
517        @Override
518        protected boolean allowFilterResult(
519                BroadcastFilter filter, List<BroadcastFilter> dest) {
520            IBinder target = filter.receiverList.receiver.asBinder();
521            for (int i=dest.size()-1; i>=0; i--) {
522                if (dest.get(i).receiverList.receiver.asBinder() == target) {
523                    return false;
524                }
525            }
526            return true;
527        }
528
529        @Override
530        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
531            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
532                    || userId == filter.owningUserId) {
533                return super.newResult(filter, match, userId);
534            }
535            return null;
536        }
537
538        @Override
539        protected BroadcastFilter[] newArray(int size) {
540            return new BroadcastFilter[size];
541        }
542
543        @Override
544        protected String packageForFilter(BroadcastFilter filter) {
545            return filter.packageName;
546        }
547    };
548
549    /**
550     * State of all active sticky broadcasts per user.  Keys are the action of the
551     * sticky Intent, values are an ArrayList of all broadcasted intents with
552     * that action (which should usually be one).  The SparseArray is keyed
553     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
554     * for stickies that are sent to all users.
555     */
556    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
557            new SparseArray<HashMap<String, ArrayList<Intent>>>();
558
559    final ActiveServices mServices;
560
561    /**
562     * Backup/restore process management
563     */
564    String mBackupAppName = null;
565    BackupRecord mBackupTarget = null;
566
567    /**
568     * List of PendingThumbnailsRecord objects of clients who are still
569     * waiting to receive all of the thumbnails for a task.
570     */
571    final ArrayList mPendingThumbnails = new ArrayList();
572
573    /**
574     * List of HistoryRecord objects that have been finished and must
575     * still report back to a pending thumbnail receiver.
576     */
577    final ArrayList mCancelledThumbnails = new ArrayList();
578
579    final ProviderMap mProviderMap;
580
581    /**
582     * List of content providers who have clients waiting for them.  The
583     * application is currently being launched and the provider will be
584     * removed from this list once it is published.
585     */
586    final ArrayList<ContentProviderRecord> mLaunchingProviders
587            = new ArrayList<ContentProviderRecord>();
588
589    /**
590     * Global set of specific Uri permissions that have been granted.
591     */
592    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
593            = new SparseArray<HashMap<Uri, UriPermission>>();
594
595    CoreSettingsObserver mCoreSettingsObserver;
596
597    /**
598     * Thread-local storage used to carry caller permissions over through
599     * indirect content-provider access.
600     * @see #ActivityManagerService.openContentUri()
601     */
602    private class Identity {
603        public int pid;
604        public int uid;
605
606        Identity(int _pid, int _uid) {
607            pid = _pid;
608            uid = _uid;
609        }
610    }
611
612    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
613
614    /**
615     * All information we have collected about the runtime performance of
616     * any user id that can impact battery performance.
617     */
618    final BatteryStatsService mBatteryStatsService;
619
620    /**
621     * information about component usage
622     */
623    final UsageStatsService mUsageStatsService;
624
625    /**
626     * Current configuration information.  HistoryRecord objects are given
627     * a reference to this object to indicate which configuration they are
628     * currently running in, so this object must be kept immutable.
629     */
630    Configuration mConfiguration = new Configuration();
631
632    /**
633     * Current sequencing integer of the configuration, for skipping old
634     * configurations.
635     */
636    int mConfigurationSeq = 0;
637
638    /**
639     * Hardware-reported OpenGLES version.
640     */
641    final int GL_ES_VERSION;
642
643    /**
644     * List of initialization arguments to pass to all processes when binding applications to them.
645     * For example, references to the commonly used services.
646     */
647    HashMap<String, IBinder> mAppBindArgs;
648
649    /**
650     * Temporary to avoid allocations.  Protected by main lock.
651     */
652    final StringBuilder mStringBuilder = new StringBuilder(256);
653
654    /**
655     * Used to control how we initialize the service.
656     */
657    boolean mStartRunning = false;
658    ComponentName mTopComponent;
659    String mTopAction;
660    String mTopData;
661    boolean mProcessesReady = false;
662    boolean mSystemReady = false;
663    boolean mBooting = false;
664    boolean mWaitingUpdate = false;
665    boolean mDidUpdate = false;
666    boolean mOnBattery = false;
667    boolean mLaunchWarningShown = false;
668
669    Context mContext;
670
671    int mFactoryTest;
672
673    boolean mCheckedForSetup;
674
675    /**
676     * The time at which we will allow normal application switches again,
677     * after a call to {@link #stopAppSwitches()}.
678     */
679    long mAppSwitchesAllowedTime;
680
681    /**
682     * This is set to true after the first switch after mAppSwitchesAllowedTime
683     * is set; any switches after that will clear the time.
684     */
685    boolean mDidAppSwitch;
686
687    /**
688     * Last time (in realtime) at which we checked for power usage.
689     */
690    long mLastPowerCheckRealtime;
691
692    /**
693     * Last time (in uptime) at which we checked for power usage.
694     */
695    long mLastPowerCheckUptime;
696
697    /**
698     * Set while we are wanting to sleep, to prevent any
699     * activities from being started/resumed.
700     */
701    boolean mSleeping = false;
702
703    /**
704     * State of external calls telling us if the device is asleep.
705     */
706    boolean mWentToSleep = false;
707
708    /**
709     * State of external call telling us if the lock screen is shown.
710     */
711    boolean mLockScreenShown = false;
712
713    /**
714     * Set if we are shutting down the system, similar to sleeping.
715     */
716    boolean mShuttingDown = false;
717
718    /**
719     * Task identifier that activities are currently being started
720     * in.  Incremented each time a new task is created.
721     * todo: Replace this with a TokenSpace class that generates non-repeating
722     * integers that won't wrap.
723     */
724    int mCurTask = 1;
725
726    /**
727     * Current sequence id for oom_adj computation traversal.
728     */
729    int mAdjSeq = 0;
730
731    /**
732     * Current sequence id for process LRU updating.
733     */
734    int mLruSeq = 0;
735
736    /**
737     * Keep track of the non-hidden/empty process we last found, to help
738     * determine how to distribute hidden/empty processes next time.
739     */
740    int mNumNonHiddenProcs = 0;
741
742    /**
743     * Keep track of the number of hidden procs, to balance oom adj
744     * distribution between those and empty procs.
745     */
746    int mNumHiddenProcs = 0;
747
748    /**
749     * Keep track of the number of service processes we last found, to
750     * determine on the next iteration which should be B services.
751     */
752    int mNumServiceProcs = 0;
753    int mNewNumServiceProcs = 0;
754
755    /**
756     * System monitoring: number of processes that died since the last
757     * N procs were started.
758     */
759    int[] mProcDeaths = new int[20];
760
761    /**
762     * This is set if we had to do a delayed dexopt of an app before launching
763     * it, to increasing the ANR timeouts in that case.
764     */
765    boolean mDidDexOpt;
766
767    String mDebugApp = null;
768    boolean mWaitForDebugger = false;
769    boolean mDebugTransient = false;
770    String mOrigDebugApp = null;
771    boolean mOrigWaitForDebugger = false;
772    boolean mAlwaysFinishActivities = false;
773    IActivityController mController = null;
774    String mProfileApp = null;
775    ProcessRecord mProfileProc = null;
776    String mProfileFile;
777    ParcelFileDescriptor mProfileFd;
778    int mProfileType = 0;
779    boolean mAutoStopProfiler = false;
780    String mOpenGlTraceApp = null;
781
782    static class ProcessChangeItem {
783        static final int CHANGE_ACTIVITIES = 1<<0;
784        static final int CHANGE_IMPORTANCE= 1<<1;
785        int changes;
786        int uid;
787        int pid;
788        int importance;
789        boolean foregroundActivities;
790    }
791
792    final RemoteCallbackList<IProcessObserver> mProcessObservers
793            = new RemoteCallbackList<IProcessObserver>();
794    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
795
796    final ArrayList<ProcessChangeItem> mPendingProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798    final ArrayList<ProcessChangeItem> mAvailProcessChanges
799            = new ArrayList<ProcessChangeItem>();
800
801    /**
802     * Callback of last caller to {@link #requestPss}.
803     */
804    Runnable mRequestPssCallback;
805
806    /**
807     * Remaining processes for which we are waiting results from the last
808     * call to {@link #requestPss}.
809     */
810    final ArrayList<ProcessRecord> mRequestPssList
811            = new ArrayList<ProcessRecord>();
812
813    /**
814     * Runtime statistics collection thread.  This object's lock is used to
815     * protect all related state.
816     */
817    final Thread mProcessStatsThread;
818
819    /**
820     * Used to collect process stats when showing not responding dialog.
821     * Protected by mProcessStatsThread.
822     */
823    final ProcessStats mProcessStats = new ProcessStats(
824            MONITOR_THREAD_CPU_USAGE);
825    final AtomicLong mLastCpuTime = new AtomicLong(0);
826    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
827
828    long mLastWriteTime = 0;
829
830    /**
831     * Set to true after the system has finished booting.
832     */
833    boolean mBooted = false;
834
835    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
836    int mProcessLimitOverride = -1;
837
838    WindowManagerService mWindowManager;
839
840    static ActivityManagerService mSelf;
841    static ActivityThread mSystemThread;
842
843    private int mCurrentUserId = 0;
844    private int[] mCurrentUserArray = new int[] { 0 };
845    private UserManagerService mUserManager;
846
847    private final class AppDeathRecipient implements IBinder.DeathRecipient {
848        final ProcessRecord mApp;
849        final int mPid;
850        final IApplicationThread mAppThread;
851
852        AppDeathRecipient(ProcessRecord app, int pid,
853                IApplicationThread thread) {
854            if (localLOGV) Slog.v(
855                TAG, "New death recipient " + this
856                + " for thread " + thread.asBinder());
857            mApp = app;
858            mPid = pid;
859            mAppThread = thread;
860        }
861
862        public void binderDied() {
863            if (localLOGV) Slog.v(
864                TAG, "Death received in " + this
865                + " for thread " + mAppThread.asBinder());
866            synchronized(ActivityManagerService.this) {
867                appDiedLocked(mApp, mPid, mAppThread);
868            }
869        }
870    }
871
872    static final int SHOW_ERROR_MSG = 1;
873    static final int SHOW_NOT_RESPONDING_MSG = 2;
874    static final int SHOW_FACTORY_ERROR_MSG = 3;
875    static final int UPDATE_CONFIGURATION_MSG = 4;
876    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
877    static final int WAIT_FOR_DEBUGGER_MSG = 6;
878    static final int SERVICE_TIMEOUT_MSG = 12;
879    static final int UPDATE_TIME_ZONE = 13;
880    static final int SHOW_UID_ERROR_MSG = 14;
881    static final int IM_FEELING_LUCKY_MSG = 15;
882    static final int PROC_START_TIMEOUT_MSG = 20;
883    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
884    static final int KILL_APPLICATION_MSG = 22;
885    static final int FINALIZE_PENDING_INTENT_MSG = 23;
886    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
887    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
888    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
889    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
890    static final int CLEAR_DNS_CACHE = 28;
891    static final int UPDATE_HTTP_PROXY = 29;
892    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
893    static final int DISPATCH_PROCESSES_CHANGED = 31;
894    static final int DISPATCH_PROCESS_DIED = 32;
895    static final int REPORT_MEM_USAGE = 33;
896    static final int REPORT_USER_SWITCH_MSG = 34;
897    static final int CONTINUE_USER_SWITCH_MSG = 35;
898    static final int USER_SWITCH_TIMEOUT_MSG = 36;
899
900    static final int FIRST_ACTIVITY_STACK_MSG = 100;
901    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
902    static final int FIRST_COMPAT_MODE_MSG = 300;
903
904    AlertDialog mUidAlert;
905    CompatModeDialog mCompatModeDialog;
906    long mLastMemUsageReportTime = 0;
907
908    final Handler mHandler = new Handler() {
909        //public Handler() {
910        //    if (localLOGV) Slog.v(TAG, "Handler started!");
911        //}
912
913        public void handleMessage(Message msg) {
914            switch (msg.what) {
915            case SHOW_ERROR_MSG: {
916                HashMap data = (HashMap) msg.obj;
917                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
918                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
919                synchronized (ActivityManagerService.this) {
920                    ProcessRecord proc = (ProcessRecord)data.get("app");
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (proc != null && proc.crashDialog != null) {
923                        Slog.e(TAG, "App already has crash dialog: " + proc);
924                        if (res != null) {
925                            res.set(0);
926                        }
927                        return;
928                    }
929                    if (!showBackground && UserHandle.getAppId(proc.uid)
930                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
931                            && proc.pid != MY_PID) {
932                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
933                        if (res != null) {
934                            res.set(0);
935                        }
936                        return;
937                    }
938                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
939                        Dialog d = new AppErrorDialog(mContext,
940                                ActivityManagerService.this, res, proc);
941                        d.show();
942                        proc.crashDialog = d;
943                    } else {
944                        // The device is asleep, so just pretend that the user
945                        // saw a crash dialog and hit "force quit".
946                        if (res != null) {
947                            res.set(0);
948                        }
949                    }
950                }
951
952                ensureBootCompleted();
953            } break;
954            case SHOW_NOT_RESPONDING_MSG: {
955                synchronized (ActivityManagerService.this) {
956                    HashMap data = (HashMap) msg.obj;
957                    ProcessRecord proc = (ProcessRecord)data.get("app");
958                    if (proc != null && proc.anrDialog != null) {
959                        Slog.e(TAG, "App already has anr dialog: " + proc);
960                        return;
961                    }
962
963                    Intent intent = new Intent("android.intent.action.ANR");
964                    if (!mProcessesReady) {
965                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
966                                | Intent.FLAG_RECEIVER_FOREGROUND);
967                    }
968                    broadcastIntentLocked(null, null, intent,
969                            null, null, 0, null, null, null,
970                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
971
972                    if (mShowDialogs) {
973                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
974                                mContext, proc, (ActivityRecord)data.get("activity"),
975                                msg.arg1 != 0);
976                        d.show();
977                        proc.anrDialog = d;
978                    } else {
979                        // Just kill the app if there is no dialog to be shown.
980                        killAppAtUsersRequest(proc, null);
981                    }
982                }
983
984                ensureBootCompleted();
985            } break;
986            case SHOW_STRICT_MODE_VIOLATION_MSG: {
987                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
988                synchronized (ActivityManagerService.this) {
989                    ProcessRecord proc = (ProcessRecord) data.get("app");
990                    if (proc == null) {
991                        Slog.e(TAG, "App not found when showing strict mode dialog.");
992                        break;
993                    }
994                    if (proc.crashDialog != null) {
995                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
996                        return;
997                    }
998                    AppErrorResult res = (AppErrorResult) data.get("result");
999                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1000                        Dialog d = new StrictModeViolationDialog(mContext,
1001                                ActivityManagerService.this, res, proc);
1002                        d.show();
1003                        proc.crashDialog = d;
1004                    } else {
1005                        // The device is asleep, so just pretend that the user
1006                        // saw a crash dialog and hit "force quit".
1007                        res.set(0);
1008                    }
1009                }
1010                ensureBootCompleted();
1011            } break;
1012            case SHOW_FACTORY_ERROR_MSG: {
1013                Dialog d = new FactoryErrorDialog(
1014                    mContext, msg.getData().getCharSequence("msg"));
1015                d.show();
1016                ensureBootCompleted();
1017            } break;
1018            case UPDATE_CONFIGURATION_MSG: {
1019                final ContentResolver resolver = mContext.getContentResolver();
1020                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1021            } break;
1022            case GC_BACKGROUND_PROCESSES_MSG: {
1023                synchronized (ActivityManagerService.this) {
1024                    performAppGcsIfAppropriateLocked();
1025                }
1026            } break;
1027            case WAIT_FOR_DEBUGGER_MSG: {
1028                synchronized (ActivityManagerService.this) {
1029                    ProcessRecord app = (ProcessRecord)msg.obj;
1030                    if (msg.arg1 != 0) {
1031                        if (!app.waitedForDebugger) {
1032                            Dialog d = new AppWaitingForDebuggerDialog(
1033                                    ActivityManagerService.this,
1034                                    mContext, app);
1035                            app.waitDialog = d;
1036                            app.waitedForDebugger = true;
1037                            d.show();
1038                        }
1039                    } else {
1040                        if (app.waitDialog != null) {
1041                            app.waitDialog.dismiss();
1042                            app.waitDialog = null;
1043                        }
1044                    }
1045                }
1046            } break;
1047            case SERVICE_TIMEOUT_MSG: {
1048                if (mDidDexOpt) {
1049                    mDidDexOpt = false;
1050                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1051                    nmsg.obj = msg.obj;
1052                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1053                    return;
1054                }
1055                mServices.serviceTimeout((ProcessRecord)msg.obj);
1056            } break;
1057            case UPDATE_TIME_ZONE: {
1058                synchronized (ActivityManagerService.this) {
1059                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1060                        ProcessRecord r = mLruProcesses.get(i);
1061                        if (r.thread != null) {
1062                            try {
1063                                r.thread.updateTimeZone();
1064                            } catch (RemoteException ex) {
1065                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1066                            }
1067                        }
1068                    }
1069                }
1070            } break;
1071            case CLEAR_DNS_CACHE: {
1072                synchronized (ActivityManagerService.this) {
1073                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1074                        ProcessRecord r = mLruProcesses.get(i);
1075                        if (r.thread != null) {
1076                            try {
1077                                r.thread.clearDnsCache();
1078                            } catch (RemoteException ex) {
1079                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1080                            }
1081                        }
1082                    }
1083                }
1084            } break;
1085            case UPDATE_HTTP_PROXY: {
1086                ProxyProperties proxy = (ProxyProperties)msg.obj;
1087                String host = "";
1088                String port = "";
1089                String exclList = "";
1090                if (proxy != null) {
1091                    host = proxy.getHost();
1092                    port = Integer.toString(proxy.getPort());
1093                    exclList = proxy.getExclusionList();
1094                }
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.setHttpProxy(host, port, exclList);
1101                            } catch (RemoteException ex) {
1102                                Slog.w(TAG, "Failed to update http proxy for: " +
1103                                        r.info.processName);
1104                            }
1105                        }
1106                    }
1107                }
1108            } break;
1109            case SHOW_UID_ERROR_MSG: {
1110                String title = "System UIDs Inconsistent";
1111                String text = "UIDs on the system are inconsistent, you need to wipe your"
1112                        + " data partition or your device will be unstable.";
1113                Log.e(TAG, title + ": " + text);
1114                if (mShowDialogs) {
1115                    // XXX This is a temporary dialog, no need to localize.
1116                    AlertDialog d = new BaseErrorDialog(mContext);
1117                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1118                    d.setCancelable(false);
1119                    d.setTitle(title);
1120                    d.setMessage(text);
1121                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1122                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1123                    mUidAlert = d;
1124                    d.show();
1125                }
1126            } break;
1127            case IM_FEELING_LUCKY_MSG: {
1128                if (mUidAlert != null) {
1129                    mUidAlert.dismiss();
1130                    mUidAlert = null;
1131                }
1132            } break;
1133            case PROC_START_TIMEOUT_MSG: {
1134                if (mDidDexOpt) {
1135                    mDidDexOpt = false;
1136                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1137                    nmsg.obj = msg.obj;
1138                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1139                    return;
1140                }
1141                ProcessRecord app = (ProcessRecord)msg.obj;
1142                synchronized (ActivityManagerService.this) {
1143                    processStartTimedOutLocked(app);
1144                }
1145            } break;
1146            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1147                synchronized (ActivityManagerService.this) {
1148                    doPendingActivityLaunchesLocked(true);
1149                }
1150            } break;
1151            case KILL_APPLICATION_MSG: {
1152                synchronized (ActivityManagerService.this) {
1153                    int appid = msg.arg1;
1154                    boolean restart = (msg.arg2 == 1);
1155                    String pkg = (String) msg.obj;
1156                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1157                            UserHandle.USER_ALL);
1158                }
1159            } break;
1160            case FINALIZE_PENDING_INTENT_MSG: {
1161                ((PendingIntentRecord)msg.obj).completeFinalize();
1162            } break;
1163            case POST_HEAVY_NOTIFICATION_MSG: {
1164                INotificationManager inm = NotificationManager.getService();
1165                if (inm == null) {
1166                    return;
1167                }
1168
1169                ActivityRecord root = (ActivityRecord)msg.obj;
1170                ProcessRecord process = root.app;
1171                if (process == null) {
1172                    return;
1173                }
1174
1175                try {
1176                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1177                    String text = mContext.getString(R.string.heavy_weight_notification,
1178                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1179                    Notification notification = new Notification();
1180                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1181                    notification.when = 0;
1182                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1183                    notification.tickerText = text;
1184                    notification.defaults = 0; // please be quiet
1185                    notification.sound = null;
1186                    notification.vibrate = null;
1187                    notification.setLatestEventInfo(context, text,
1188                            mContext.getText(R.string.heavy_weight_notification_detail),
1189                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1190                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1191                                    new UserHandle(root.userId)));
1192
1193                    try {
1194                        int[] outId = new int[1];
1195                        inm.enqueueNotificationWithTag("android", null,
1196                                R.string.heavy_weight_notification,
1197                                notification, outId, root.userId);
1198                    } catch (RuntimeException e) {
1199                        Slog.w(ActivityManagerService.TAG,
1200                                "Error showing notification for heavy-weight app", e);
1201                    } catch (RemoteException e) {
1202                    }
1203                } catch (NameNotFoundException e) {
1204                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1205                }
1206            } break;
1207            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1208                INotificationManager inm = NotificationManager.getService();
1209                if (inm == null) {
1210                    return;
1211                }
1212                try {
1213                    inm.cancelNotificationWithTag("android", null,
1214                            R.string.heavy_weight_notification,  msg.arg1);
1215                } catch (RuntimeException e) {
1216                    Slog.w(ActivityManagerService.TAG,
1217                            "Error canceling notification for service", e);
1218                } catch (RemoteException e) {
1219                }
1220            } break;
1221            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1222                synchronized (ActivityManagerService.this) {
1223                    checkExcessivePowerUsageLocked(true);
1224                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1225                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1226                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1227                }
1228            } break;
1229            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1230                synchronized (ActivityManagerService.this) {
1231                    ActivityRecord ar = (ActivityRecord)msg.obj;
1232                    if (mCompatModeDialog != null) {
1233                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1234                                ar.info.applicationInfo.packageName)) {
1235                            return;
1236                        }
1237                        mCompatModeDialog.dismiss();
1238                        mCompatModeDialog = null;
1239                    }
1240                    if (ar != null && false) {
1241                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1242                                ar.packageName)) {
1243                            int mode = mCompatModePackages.computeCompatModeLocked(
1244                                    ar.info.applicationInfo);
1245                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1246                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1247                                mCompatModeDialog = new CompatModeDialog(
1248                                        ActivityManagerService.this, mContext,
1249                                        ar.info.applicationInfo);
1250                                mCompatModeDialog.show();
1251                            }
1252                        }
1253                    }
1254                }
1255                break;
1256            }
1257            case DISPATCH_PROCESSES_CHANGED: {
1258                dispatchProcessesChanged();
1259                break;
1260            }
1261            case DISPATCH_PROCESS_DIED: {
1262                final int pid = msg.arg1;
1263                final int uid = msg.arg2;
1264                dispatchProcessDied(pid, uid);
1265                break;
1266            }
1267            case REPORT_MEM_USAGE: {
1268                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1269                if (!isDebuggable) {
1270                    return;
1271                }
1272                synchronized (ActivityManagerService.this) {
1273                    long now = SystemClock.uptimeMillis();
1274                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1275                        // Don't report more than every 5 minutes to somewhat
1276                        // avoid spamming.
1277                        return;
1278                    }
1279                    mLastMemUsageReportTime = now;
1280                }
1281                Thread thread = new Thread() {
1282                    @Override public void run() {
1283                        StringBuilder dropBuilder = new StringBuilder(1024);
1284                        StringBuilder logBuilder = new StringBuilder(1024);
1285                        StringWriter oomSw = new StringWriter();
1286                        PrintWriter oomPw = new PrintWriter(oomSw);
1287                        StringWriter catSw = new StringWriter();
1288                        PrintWriter catPw = new PrintWriter(catSw);
1289                        String[] emptyArgs = new String[] { };
1290                        StringBuilder tag = new StringBuilder(128);
1291                        StringBuilder stack = new StringBuilder(128);
1292                        tag.append("Low on memory -- ");
1293                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1294                                tag, stack);
1295                        dropBuilder.append(stack);
1296                        dropBuilder.append('\n');
1297                        dropBuilder.append('\n');
1298                        String oomString = oomSw.toString();
1299                        dropBuilder.append(oomString);
1300                        dropBuilder.append('\n');
1301                        logBuilder.append(oomString);
1302                        try {
1303                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1304                                    "procrank", });
1305                            final InputStreamReader converter = new InputStreamReader(
1306                                    proc.getInputStream());
1307                            BufferedReader in = new BufferedReader(converter);
1308                            String line;
1309                            while (true) {
1310                                line = in.readLine();
1311                                if (line == null) {
1312                                    break;
1313                                }
1314                                if (line.length() > 0) {
1315                                    logBuilder.append(line);
1316                                    logBuilder.append('\n');
1317                                }
1318                                dropBuilder.append(line);
1319                                dropBuilder.append('\n');
1320                            }
1321                            converter.close();
1322                        } catch (IOException e) {
1323                        }
1324                        synchronized (ActivityManagerService.this) {
1325                            catPw.println();
1326                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1327                            catPw.println();
1328                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1329                                    false, false, null);
1330                            catPw.println();
1331                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1332                        }
1333                        dropBuilder.append(catSw.toString());
1334                        addErrorToDropBox("lowmem", null, "system_server", null,
1335                                null, tag.toString(), dropBuilder.toString(), null, null);
1336                        Slog.i(TAG, logBuilder.toString());
1337                        synchronized (ActivityManagerService.this) {
1338                            long now = SystemClock.uptimeMillis();
1339                            if (mLastMemUsageReportTime < now) {
1340                                mLastMemUsageReportTime = now;
1341                            }
1342                        }
1343                    }
1344                };
1345                thread.start();
1346                break;
1347            }
1348            case REPORT_USER_SWITCH_MSG: {
1349                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1350                break;
1351            }
1352            case CONTINUE_USER_SWITCH_MSG: {
1353                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1354                break;
1355            }
1356            case USER_SWITCH_TIMEOUT_MSG: {
1357                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1358                break;
1359            }
1360            }
1361        }
1362    };
1363
1364    public static void setSystemProcess() {
1365        try {
1366            ActivityManagerService m = mSelf;
1367
1368            ServiceManager.addService("activity", m, true);
1369            ServiceManager.addService("meminfo", new MemBinder(m));
1370            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1371            ServiceManager.addService("dbinfo", new DbBinder(m));
1372            if (MONITOR_CPU_USAGE) {
1373                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1374            }
1375            ServiceManager.addService("permission", new PermissionController(m));
1376
1377            ApplicationInfo info =
1378                mSelf.mContext.getPackageManager().getApplicationInfo(
1379                            "android", STOCK_PM_FLAGS);
1380            mSystemThread.installSystemApplicationInfo(info);
1381
1382            synchronized (mSelf) {
1383                ProcessRecord app = mSelf.newProcessRecordLocked(
1384                        mSystemThread.getApplicationThread(), info,
1385                        info.processName, false);
1386                app.persistent = true;
1387                app.pid = MY_PID;
1388                app.maxAdj = ProcessList.SYSTEM_ADJ;
1389                mSelf.mProcessNames.put(app.processName, app.uid, app);
1390                synchronized (mSelf.mPidsSelfLocked) {
1391                    mSelf.mPidsSelfLocked.put(app.pid, app);
1392                }
1393                mSelf.updateLruProcessLocked(app, true);
1394            }
1395        } catch (PackageManager.NameNotFoundException e) {
1396            throw new RuntimeException(
1397                    "Unable to find android system package", e);
1398        }
1399    }
1400
1401    public void setWindowManager(WindowManagerService wm) {
1402        mWindowManager = wm;
1403    }
1404
1405    public static final Context main(int factoryTest) {
1406        AThread thr = new AThread();
1407        thr.start();
1408
1409        synchronized (thr) {
1410            while (thr.mService == null) {
1411                try {
1412                    thr.wait();
1413                } catch (InterruptedException e) {
1414                }
1415            }
1416        }
1417
1418        ActivityManagerService m = thr.mService;
1419        mSelf = m;
1420        ActivityThread at = ActivityThread.systemMain();
1421        mSystemThread = at;
1422        Context context = at.getSystemContext();
1423        context.setTheme(android.R.style.Theme_Holo);
1424        m.mContext = context;
1425        m.mFactoryTest = factoryTest;
1426        m.mMainStack = new ActivityStack(m, context, true);
1427
1428        m.mBatteryStatsService.publish(context);
1429        m.mUsageStatsService.publish(context);
1430
1431        synchronized (thr) {
1432            thr.mReady = true;
1433            thr.notifyAll();
1434        }
1435
1436        m.startRunning(null, null, null, null);
1437
1438        return context;
1439    }
1440
1441    public static ActivityManagerService self() {
1442        return mSelf;
1443    }
1444
1445    static class AThread extends Thread {
1446        ActivityManagerService mService;
1447        boolean mReady = false;
1448
1449        public AThread() {
1450            super("ActivityManager");
1451        }
1452
1453        public void run() {
1454            Looper.prepare();
1455
1456            android.os.Process.setThreadPriority(
1457                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1458            android.os.Process.setCanSelfBackground(false);
1459
1460            ActivityManagerService m = new ActivityManagerService();
1461
1462            synchronized (this) {
1463                mService = m;
1464                notifyAll();
1465            }
1466
1467            synchronized (this) {
1468                while (!mReady) {
1469                    try {
1470                        wait();
1471                    } catch (InterruptedException e) {
1472                    }
1473                }
1474            }
1475
1476            // For debug builds, log event loop stalls to dropbox for analysis.
1477            if (StrictMode.conditionallyEnableDebugLogging()) {
1478                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1479            }
1480
1481            Looper.loop();
1482        }
1483    }
1484
1485    static class MemBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        MemBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump meminfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1502                    false, null, null, null);
1503        }
1504    }
1505
1506    static class GraphicsBinder extends Binder {
1507        ActivityManagerService mActivityManagerService;
1508        GraphicsBinder(ActivityManagerService activityManagerService) {
1509            mActivityManagerService = activityManagerService;
1510        }
1511
1512        @Override
1513        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1514            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1515                    != PackageManager.PERMISSION_GRANTED) {
1516                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1517                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1518                        + " without permission " + android.Manifest.permission.DUMP);
1519                return;
1520            }
1521
1522            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1523        }
1524    }
1525
1526    static class DbBinder extends Binder {
1527        ActivityManagerService mActivityManagerService;
1528        DbBinder(ActivityManagerService activityManagerService) {
1529            mActivityManagerService = activityManagerService;
1530        }
1531
1532        @Override
1533        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1534            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1535                    != PackageManager.PERMISSION_GRANTED) {
1536                pw.println("Permission Denial: can't dump dbinfo from from pid="
1537                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1538                        + " without permission " + android.Manifest.permission.DUMP);
1539                return;
1540            }
1541
1542            mActivityManagerService.dumpDbInfo(fd, pw, args);
1543        }
1544    }
1545
1546    static class CpuBinder extends Binder {
1547        ActivityManagerService mActivityManagerService;
1548        CpuBinder(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 cpuinfo from from pid="
1557                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1558                        + " without permission " + android.Manifest.permission.DUMP);
1559                return;
1560            }
1561
1562            synchronized (mActivityManagerService.mProcessStatsThread) {
1563                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1564                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1565                        SystemClock.uptimeMillis()));
1566            }
1567        }
1568    }
1569
1570    private ActivityManagerService() {
1571        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1572
1573        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1574        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1575        mBroadcastQueues[0] = mFgBroadcastQueue;
1576        mBroadcastQueues[1] = mBgBroadcastQueue;
1577
1578        mServices = new ActiveServices(this);
1579        mProviderMap = new ProviderMap(this);
1580
1581        File dataDir = Environment.getDataDirectory();
1582        File systemDir = new File(dataDir, "system");
1583        systemDir.mkdirs();
1584        mBatteryStatsService = new BatteryStatsService(new File(
1585                systemDir, "batterystats.bin").toString());
1586        mBatteryStatsService.getActiveStatistics().readLocked();
1587        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1588        mOnBattery = DEBUG_POWER ? true
1589                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1590        mBatteryStatsService.getActiveStatistics().setCallback(this);
1591
1592        mUsageStatsService = new UsageStatsService(new File(
1593                systemDir, "usagestats").toString());
1594        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1595
1596        // User 0 is the first and only user that runs at boot.
1597        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1598        mUserLru.add(Integer.valueOf(0));
1599        updateStartedUserArrayLocked();
1600
1601        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1602            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1603
1604        mConfiguration.setToDefaults();
1605        mConfiguration.setLocale(Locale.getDefault());
1606
1607        mConfigurationSeq = mConfiguration.seq = 1;
1608        mProcessStats.init();
1609
1610        mCompatModePackages = new CompatModePackages(this, systemDir);
1611
1612        // Add ourself to the Watchdog monitors.
1613        Watchdog.getInstance().addMonitor(this);
1614
1615        mProcessStatsThread = new Thread("ProcessStats") {
1616            public void run() {
1617                while (true) {
1618                    try {
1619                        try {
1620                            synchronized(this) {
1621                                final long now = SystemClock.uptimeMillis();
1622                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1623                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1624                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1625                                //        + ", write delay=" + nextWriteDelay);
1626                                if (nextWriteDelay < nextCpuDelay) {
1627                                    nextCpuDelay = nextWriteDelay;
1628                                }
1629                                if (nextCpuDelay > 0) {
1630                                    mProcessStatsMutexFree.set(true);
1631                                    this.wait(nextCpuDelay);
1632                                }
1633                            }
1634                        } catch (InterruptedException e) {
1635                        }
1636                        updateCpuStatsNow();
1637                    } catch (Exception e) {
1638                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1639                    }
1640                }
1641            }
1642        };
1643        mProcessStatsThread.start();
1644    }
1645
1646    @Override
1647    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1648            throws RemoteException {
1649        if (code == SYSPROPS_TRANSACTION) {
1650            // We need to tell all apps about the system property change.
1651            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1652            synchronized(this) {
1653                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1654                    final int NA = apps.size();
1655                    for (int ia=0; ia<NA; ia++) {
1656                        ProcessRecord app = apps.valueAt(ia);
1657                        if (app.thread != null) {
1658                            procs.add(app.thread.asBinder());
1659                        }
1660                    }
1661                }
1662            }
1663
1664            int N = procs.size();
1665            for (int i=0; i<N; i++) {
1666                Parcel data2 = Parcel.obtain();
1667                try {
1668                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1669                } catch (RemoteException e) {
1670                }
1671                data2.recycle();
1672            }
1673        }
1674        try {
1675            return super.onTransact(code, data, reply, flags);
1676        } catch (RuntimeException e) {
1677            // The activity manager only throws security exceptions, so let's
1678            // log all others.
1679            if (!(e instanceof SecurityException)) {
1680                Slog.e(TAG, "Activity Manager Crash", e);
1681            }
1682            throw e;
1683        }
1684    }
1685
1686    void updateCpuStats() {
1687        final long now = SystemClock.uptimeMillis();
1688        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1689            return;
1690        }
1691        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1692            synchronized (mProcessStatsThread) {
1693                mProcessStatsThread.notify();
1694            }
1695        }
1696    }
1697
1698    void updateCpuStatsNow() {
1699        synchronized (mProcessStatsThread) {
1700            mProcessStatsMutexFree.set(false);
1701            final long now = SystemClock.uptimeMillis();
1702            boolean haveNewCpuStats = false;
1703
1704            if (MONITOR_CPU_USAGE &&
1705                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1706                mLastCpuTime.set(now);
1707                haveNewCpuStats = true;
1708                mProcessStats.update();
1709                //Slog.i(TAG, mProcessStats.printCurrentState());
1710                //Slog.i(TAG, "Total CPU usage: "
1711                //        + mProcessStats.getTotalCpuPercent() + "%");
1712
1713                // Slog the cpu usage if the property is set.
1714                if ("true".equals(SystemProperties.get("events.cpu"))) {
1715                    int user = mProcessStats.getLastUserTime();
1716                    int system = mProcessStats.getLastSystemTime();
1717                    int iowait = mProcessStats.getLastIoWaitTime();
1718                    int irq = mProcessStats.getLastIrqTime();
1719                    int softIrq = mProcessStats.getLastSoftIrqTime();
1720                    int idle = mProcessStats.getLastIdleTime();
1721
1722                    int total = user + system + iowait + irq + softIrq + idle;
1723                    if (total == 0) total = 1;
1724
1725                    EventLog.writeEvent(EventLogTags.CPU,
1726                            ((user+system+iowait+irq+softIrq) * 100) / total,
1727                            (user * 100) / total,
1728                            (system * 100) / total,
1729                            (iowait * 100) / total,
1730                            (irq * 100) / total,
1731                            (softIrq * 100) / total);
1732                }
1733            }
1734
1735            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1736            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1737            synchronized(bstats) {
1738                synchronized(mPidsSelfLocked) {
1739                    if (haveNewCpuStats) {
1740                        if (mOnBattery) {
1741                            int perc = bstats.startAddingCpuLocked();
1742                            int totalUTime = 0;
1743                            int totalSTime = 0;
1744                            final int N = mProcessStats.countStats();
1745                            for (int i=0; i<N; i++) {
1746                                ProcessStats.Stats st = mProcessStats.getStats(i);
1747                                if (!st.working) {
1748                                    continue;
1749                                }
1750                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1751                                int otherUTime = (st.rel_utime*perc)/100;
1752                                int otherSTime = (st.rel_stime*perc)/100;
1753                                totalUTime += otherUTime;
1754                                totalSTime += otherSTime;
1755                                if (pr != null) {
1756                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1757                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1758                                            st.rel_stime-otherSTime);
1759                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1760                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1761                                } else {
1762                                    BatteryStatsImpl.Uid.Proc ps =
1763                                            bstats.getProcessStatsLocked(st.name, st.pid);
1764                                    if (ps != null) {
1765                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1766                                                st.rel_stime-otherSTime);
1767                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1768                                    }
1769                                }
1770                            }
1771                            bstats.finishAddingCpuLocked(perc, totalUTime,
1772                                    totalSTime, cpuSpeedTimes);
1773                        }
1774                    }
1775                }
1776
1777                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1778                    mLastWriteTime = now;
1779                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1780                }
1781            }
1782        }
1783    }
1784
1785    @Override
1786    public void batteryNeedsCpuUpdate() {
1787        updateCpuStatsNow();
1788    }
1789
1790    @Override
1791    public void batteryPowerChanged(boolean onBattery) {
1792        // When plugging in, update the CPU stats first before changing
1793        // the plug state.
1794        updateCpuStatsNow();
1795        synchronized (this) {
1796            synchronized(mPidsSelfLocked) {
1797                mOnBattery = DEBUG_POWER ? true : onBattery;
1798            }
1799        }
1800    }
1801
1802    /**
1803     * Initialize the application bind args. These are passed to each
1804     * process when the bindApplication() IPC is sent to the process. They're
1805     * lazily setup to make sure the services are running when they're asked for.
1806     */
1807    private HashMap<String, IBinder> getCommonServicesLocked() {
1808        if (mAppBindArgs == null) {
1809            mAppBindArgs = new HashMap<String, IBinder>();
1810
1811            // Setup the application init args
1812            mAppBindArgs.put("package", ServiceManager.getService("package"));
1813            mAppBindArgs.put("window", ServiceManager.getService("window"));
1814            mAppBindArgs.put(Context.ALARM_SERVICE,
1815                    ServiceManager.getService(Context.ALARM_SERVICE));
1816        }
1817        return mAppBindArgs;
1818    }
1819
1820    final void setFocusedActivityLocked(ActivityRecord r) {
1821        if (mFocusedActivity != r) {
1822            mFocusedActivity = r;
1823            if (r != null) {
1824                mWindowManager.setFocusedApp(r.appToken, true);
1825            }
1826        }
1827    }
1828
1829    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1830        // put it on the LRU to keep track of when it should be exited.
1831        int lrui = mLruProcesses.indexOf(app);
1832        if (lrui >= 0) mLruProcesses.remove(lrui);
1833
1834        int i = mLruProcesses.size()-1;
1835        int skipTop = 0;
1836
1837        app.lruSeq = mLruSeq;
1838
1839        // compute the new weight for this process.
1840        app.lastActivityTime = SystemClock.uptimeMillis();
1841        if (app.activities.size() > 0) {
1842            // If this process has activities, we more strongly want to keep
1843            // it around.
1844            app.lruWeight = app.lastActivityTime;
1845        } else if (app.pubProviders.size() > 0) {
1846            // If this process contains content providers, we want to keep
1847            // it a little more strongly.
1848            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1849            // Also don't let it kick out the first few "real" hidden processes.
1850            skipTop = ProcessList.MIN_HIDDEN_APPS;
1851        } else {
1852            // If this process doesn't have activities, we less strongly
1853            // want to keep it around, and generally want to avoid getting
1854            // in front of any very recently used activities.
1855            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1856            // Also don't let it kick out the first few "real" hidden processes.
1857            skipTop = ProcessList.MIN_HIDDEN_APPS;
1858        }
1859
1860        while (i >= 0) {
1861            ProcessRecord p = mLruProcesses.get(i);
1862            // If this app shouldn't be in front of the first N background
1863            // apps, then skip over that many that are currently hidden.
1864            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1865                skipTop--;
1866            }
1867            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1868                mLruProcesses.add(i+1, app);
1869                break;
1870            }
1871            i--;
1872        }
1873        if (i < 0) {
1874            mLruProcesses.add(0, app);
1875        }
1876
1877        // If the app is currently using a content provider or service,
1878        // bump those processes as well.
1879        if (app.connections.size() > 0) {
1880            for (ConnectionRecord cr : app.connections) {
1881                if (cr.binding != null && cr.binding.service != null
1882                        && cr.binding.service.app != null
1883                        && cr.binding.service.app.lruSeq != mLruSeq) {
1884                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1885                }
1886            }
1887        }
1888        for (int j=app.conProviders.size()-1; j>=0; j--) {
1889            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1890            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1891                updateLruProcessInternalLocked(cpr.proc, i+1);
1892            }
1893        }
1894    }
1895
1896    final void updateLruProcessLocked(ProcessRecord app,
1897            boolean oomAdj) {
1898        mLruSeq++;
1899        updateLruProcessInternalLocked(app, 0);
1900
1901        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1902        if (oomAdj) {
1903            updateOomAdjLocked();
1904        }
1905    }
1906
1907    final ProcessRecord getProcessRecordLocked(
1908            String processName, int uid) {
1909        if (uid == Process.SYSTEM_UID) {
1910            // The system gets to run in any process.  If there are multiple
1911            // processes with the same uid, just pick the first (this
1912            // should never happen).
1913            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1914                    processName);
1915            if (procs == null) return null;
1916            final int N = procs.size();
1917            for (int i = 0; i < N; i++) {
1918                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1919            }
1920        }
1921        ProcessRecord proc = mProcessNames.get(processName, uid);
1922        return proc;
1923    }
1924
1925    void ensurePackageDexOpt(String packageName) {
1926        IPackageManager pm = AppGlobals.getPackageManager();
1927        try {
1928            if (pm.performDexOpt(packageName)) {
1929                mDidDexOpt = true;
1930            }
1931        } catch (RemoteException e) {
1932        }
1933    }
1934
1935    boolean isNextTransitionForward() {
1936        int transit = mWindowManager.getPendingAppTransition();
1937        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1938                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1939                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1940    }
1941
1942    final ProcessRecord startProcessLocked(String processName,
1943            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1944            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1945            boolean isolated) {
1946        ProcessRecord app;
1947        if (!isolated) {
1948            app = getProcessRecordLocked(processName, info.uid);
1949        } else {
1950            // If this is an isolated process, it can't re-use an existing process.
1951            app = null;
1952        }
1953        // We don't have to do anything more if:
1954        // (1) There is an existing application record; and
1955        // (2) The caller doesn't think it is dead, OR there is no thread
1956        //     object attached to it so we know it couldn't have crashed; and
1957        // (3) There is a pid assigned to it, so it is either starting or
1958        //     already running.
1959        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1960                + " app=" + app + " knownToBeDead=" + knownToBeDead
1961                + " thread=" + (app != null ? app.thread : null)
1962                + " pid=" + (app != null ? app.pid : -1));
1963        if (app != null && app.pid > 0) {
1964            if (!knownToBeDead || app.thread == null) {
1965                // We already have the app running, or are waiting for it to
1966                // come up (we have a pid but not yet its thread), so keep it.
1967                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1968                // If this is a new package in the process, add the package to the list
1969                app.addPackage(info.packageName);
1970                return app;
1971            } else {
1972                // An application record is attached to a previous process,
1973                // clean it up now.
1974                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
1975                handleAppDiedLocked(app, true, true);
1976            }
1977        }
1978
1979        String hostingNameStr = hostingName != null
1980                ? hostingName.flattenToShortString() : null;
1981
1982        if (!isolated) {
1983            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1984                // If we are in the background, then check to see if this process
1985                // is bad.  If so, we will just silently fail.
1986                if (mBadProcesses.get(info.processName, info.uid) != null) {
1987                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1988                            + "/" + info.processName);
1989                    return null;
1990                }
1991            } else {
1992                // When the user is explicitly starting a process, then clear its
1993                // crash count so that we won't make it bad until they see at
1994                // least one crash dialog again, and make the process good again
1995                // if it had been bad.
1996                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1997                        + "/" + info.processName);
1998                mProcessCrashTimes.remove(info.processName, info.uid);
1999                if (mBadProcesses.get(info.processName, info.uid) != null) {
2000                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2001                            UserHandle.getUserId(info.uid), info.uid,
2002                            info.processName);
2003                    mBadProcesses.remove(info.processName, info.uid);
2004                    if (app != null) {
2005                        app.bad = false;
2006                    }
2007                }
2008            }
2009        }
2010
2011        if (app == null) {
2012            app = newProcessRecordLocked(null, info, processName, isolated);
2013            if (app == null) {
2014                Slog.w(TAG, "Failed making new process record for "
2015                        + processName + "/" + info.uid + " isolated=" + isolated);
2016                return null;
2017            }
2018            mProcessNames.put(processName, app.uid, app);
2019            if (isolated) {
2020                mIsolatedProcesses.put(app.uid, app);
2021            }
2022        } else {
2023            // If this is a new package in the process, add the package to the list
2024            app.addPackage(info.packageName);
2025        }
2026
2027        // If the system is not ready yet, then hold off on starting this
2028        // process until it is.
2029        if (!mProcessesReady
2030                && !isAllowedWhileBooting(info)
2031                && !allowWhileBooting) {
2032            if (!mProcessesOnHold.contains(app)) {
2033                mProcessesOnHold.add(app);
2034            }
2035            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2036            return app;
2037        }
2038
2039        startProcessLocked(app, hostingType, hostingNameStr);
2040        return (app.pid != 0) ? app : null;
2041    }
2042
2043    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2044        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2045    }
2046
2047    private final void startProcessLocked(ProcessRecord app,
2048            String hostingType, String hostingNameStr) {
2049        if (app.pid > 0 && app.pid != MY_PID) {
2050            synchronized (mPidsSelfLocked) {
2051                mPidsSelfLocked.remove(app.pid);
2052                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2053            }
2054            app.setPid(0);
2055        }
2056
2057        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2058                "startProcessLocked removing on hold: " + app);
2059        mProcessesOnHold.remove(app);
2060
2061        updateCpuStats();
2062
2063        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2064        mProcDeaths[0] = 0;
2065
2066        try {
2067            int uid = app.uid;
2068
2069            int[] gids = null;
2070            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2071            if (!app.isolated) {
2072                int[] permGids = null;
2073                try {
2074                    final PackageManager pm = mContext.getPackageManager();
2075                    permGids = pm.getPackageGids(app.info.packageName);
2076
2077                    if (Environment.isExternalStorageEmulated()) {
2078                        if (pm.checkPermission(
2079                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2080                                app.info.packageName) == PERMISSION_GRANTED) {
2081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2082                        } else {
2083                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2084                        }
2085                    }
2086                } catch (PackageManager.NameNotFoundException e) {
2087                    Slog.w(TAG, "Unable to retrieve gids", e);
2088                }
2089
2090                /*
2091                 * Add shared application GID so applications can share some
2092                 * resources like shared libraries
2093                 */
2094                if (permGids == null) {
2095                    gids = new int[1];
2096                } else {
2097                    gids = new int[permGids.length + 1];
2098                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2099                }
2100                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2101            }
2102            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2103                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2104                        && mTopComponent != null
2105                        && app.processName.equals(mTopComponent.getPackageName())) {
2106                    uid = 0;
2107                }
2108                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2109                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2110                    uid = 0;
2111                }
2112            }
2113            int debugFlags = 0;
2114            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2115                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2116                // Also turn on CheckJNI for debuggable apps. It's quite
2117                // awkward to turn on otherwise.
2118                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2119            }
2120            // Run the app in safe mode if its manifest requests so or the
2121            // system is booted in safe mode.
2122            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2123                Zygote.systemInSafeMode == true) {
2124                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2125            }
2126            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2127                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2128            }
2129            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2130                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2131            }
2132            if ("1".equals(SystemProperties.get("debug.assert"))) {
2133                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2134            }
2135
2136            // Start the process.  It will either succeed and return a result containing
2137            // the PID of the new process, or else throw a RuntimeException.
2138            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2139                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2140                    app.info.targetSdkVersion, null, null);
2141
2142            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2143            synchronized (bs) {
2144                if (bs.isOnBattery()) {
2145                    app.batteryStats.incStartsLocked();
2146                }
2147            }
2148
2149            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2150                    UserHandle.getUserId(uid), startResult.pid, uid,
2151                    app.processName, hostingType,
2152                    hostingNameStr != null ? hostingNameStr : "");
2153
2154            if (app.persistent) {
2155                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2156            }
2157
2158            StringBuilder buf = mStringBuilder;
2159            buf.setLength(0);
2160            buf.append("Start proc ");
2161            buf.append(app.processName);
2162            buf.append(" for ");
2163            buf.append(hostingType);
2164            if (hostingNameStr != null) {
2165                buf.append(" ");
2166                buf.append(hostingNameStr);
2167            }
2168            buf.append(": pid=");
2169            buf.append(startResult.pid);
2170            buf.append(" uid=");
2171            buf.append(uid);
2172            buf.append(" gids={");
2173            if (gids != null) {
2174                for (int gi=0; gi<gids.length; gi++) {
2175                    if (gi != 0) buf.append(", ");
2176                    buf.append(gids[gi]);
2177
2178                }
2179            }
2180            buf.append("}");
2181            Slog.i(TAG, buf.toString());
2182            app.setPid(startResult.pid);
2183            app.usingWrapper = startResult.usingWrapper;
2184            app.removed = false;
2185            synchronized (mPidsSelfLocked) {
2186                this.mPidsSelfLocked.put(startResult.pid, app);
2187                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2188                msg.obj = app;
2189                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2190                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2191            }
2192        } catch (RuntimeException e) {
2193            // XXX do better error recovery.
2194            app.setPid(0);
2195            Slog.e(TAG, "Failure starting process " + app.processName, e);
2196        }
2197    }
2198
2199    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2200        if (resumed) {
2201            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2202        } else {
2203            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2204        }
2205    }
2206
2207    boolean startHomeActivityLocked(int userId) {
2208        if (mHeadless) {
2209            // Added because none of the other calls to ensureBootCompleted seem to fire
2210            // when running headless.
2211            ensureBootCompleted();
2212            return false;
2213        }
2214
2215        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2216                && mTopAction == null) {
2217            // We are running in factory test mode, but unable to find
2218            // the factory test app, so just sit around displaying the
2219            // error message and don't try to start anything.
2220            return false;
2221        }
2222        Intent intent = new Intent(
2223            mTopAction,
2224            mTopData != null ? Uri.parse(mTopData) : null);
2225        intent.setComponent(mTopComponent);
2226        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2227            intent.addCategory(Intent.CATEGORY_HOME);
2228        }
2229        ActivityInfo aInfo =
2230            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2231        if (aInfo != null) {
2232            intent.setComponent(new ComponentName(
2233                    aInfo.applicationInfo.packageName, aInfo.name));
2234            // Don't do this if the home app is currently being
2235            // instrumented.
2236            aInfo = new ActivityInfo(aInfo);
2237            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2238            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2239                    aInfo.applicationInfo.uid);
2240            if (app == null || app.instrumentationClass == null) {
2241                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2242                mMainStack.startActivityLocked(null, intent, null, aInfo,
2243                        null, null, 0, 0, 0, 0, null, false, null);
2244            }
2245        }
2246
2247        return true;
2248    }
2249
2250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2251        ActivityInfo ai = null;
2252        ComponentName comp = intent.getComponent();
2253        try {
2254            if (comp != null) {
2255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2256            } else {
2257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2258                        intent,
2259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2260                            flags, userId);
2261
2262                if (info != null) {
2263                    ai = info.activityInfo;
2264                }
2265            }
2266        } catch (RemoteException e) {
2267            // ignore
2268        }
2269
2270        return ai;
2271    }
2272
2273    /**
2274     * Starts the "new version setup screen" if appropriate.
2275     */
2276    void startSetupActivityLocked() {
2277        // Only do this once per boot.
2278        if (mCheckedForSetup) {
2279            return;
2280        }
2281
2282        // We will show this screen if the current one is a different
2283        // version than the last one shown, and we are not running in
2284        // low-level factory test mode.
2285        final ContentResolver resolver = mContext.getContentResolver();
2286        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2287                Settings.Global.getInt(resolver,
2288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2289            mCheckedForSetup = true;
2290
2291            // See if we should be showing the platform update setup UI.
2292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2293            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2295
2296            // We don't allow third party apps to replace this.
2297            ResolveInfo ri = null;
2298            for (int i=0; ris != null && i<ris.size(); i++) {
2299                if ((ris.get(i).activityInfo.applicationInfo.flags
2300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2301                    ri = ris.get(i);
2302                    break;
2303                }
2304            }
2305
2306            if (ri != null) {
2307                String vers = ri.activityInfo.metaData != null
2308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2309                        : null;
2310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2312                            Intent.METADATA_SETUP_VERSION);
2313                }
2314                String lastVers = Settings.Secure.getString(
2315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2316                if (vers != null && !vers.equals(lastVers)) {
2317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2318                    intent.setComponent(new ComponentName(
2319                            ri.activityInfo.packageName, ri.activityInfo.name));
2320                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2321                            null, null, 0, 0, 0, 0, null, false, null);
2322                }
2323            }
2324        }
2325    }
2326
2327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2329    }
2330
2331    void enforceNotIsolatedCaller(String caller) {
2332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2333            throw new SecurityException("Isolated process not allowed to call " + caller);
2334        }
2335    }
2336
2337    public int getFrontActivityScreenCompatMode() {
2338        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2339        synchronized (this) {
2340            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2341        }
2342    }
2343
2344    public void setFrontActivityScreenCompatMode(int mode) {
2345        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2346                "setFrontActivityScreenCompatMode");
2347        synchronized (this) {
2348            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2349        }
2350    }
2351
2352    public int getPackageScreenCompatMode(String packageName) {
2353        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2354        synchronized (this) {
2355            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2356        }
2357    }
2358
2359    public void setPackageScreenCompatMode(String packageName, int mode) {
2360        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2361                "setPackageScreenCompatMode");
2362        synchronized (this) {
2363            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2364        }
2365    }
2366
2367    public boolean getPackageAskScreenCompat(String packageName) {
2368        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2369        synchronized (this) {
2370            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2371        }
2372    }
2373
2374    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2376                "setPackageAskScreenCompat");
2377        synchronized (this) {
2378            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2379        }
2380    }
2381
2382    void reportResumedActivityLocked(ActivityRecord r) {
2383        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2384        updateUsageStats(r, true);
2385    }
2386
2387    private void dispatchProcessesChanged() {
2388        int N;
2389        synchronized (this) {
2390            N = mPendingProcessChanges.size();
2391            if (mActiveProcessChanges.length < N) {
2392                mActiveProcessChanges = new ProcessChangeItem[N];
2393            }
2394            mPendingProcessChanges.toArray(mActiveProcessChanges);
2395            mAvailProcessChanges.addAll(mPendingProcessChanges);
2396            mPendingProcessChanges.clear();
2397            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2398        }
2399        int i = mProcessObservers.beginBroadcast();
2400        while (i > 0) {
2401            i--;
2402            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2403            if (observer != null) {
2404                try {
2405                    for (int j=0; j<N; j++) {
2406                        ProcessChangeItem item = mActiveProcessChanges[j];
2407                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2408                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2409                                    + item.pid + " uid=" + item.uid + ": "
2410                                    + item.foregroundActivities);
2411                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2412                                    item.foregroundActivities);
2413                        }
2414                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2415                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2416                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2417                            observer.onImportanceChanged(item.pid, item.uid,
2418                                    item.importance);
2419                        }
2420                    }
2421                } catch (RemoteException e) {
2422                }
2423            }
2424        }
2425        mProcessObservers.finishBroadcast();
2426    }
2427
2428    private void dispatchProcessDied(int pid, int uid) {
2429        int i = mProcessObservers.beginBroadcast();
2430        while (i > 0) {
2431            i--;
2432            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2433            if (observer != null) {
2434                try {
2435                    observer.onProcessDied(pid, uid);
2436                } catch (RemoteException e) {
2437                }
2438            }
2439        }
2440        mProcessObservers.finishBroadcast();
2441    }
2442
2443    final void doPendingActivityLaunchesLocked(boolean doResume) {
2444        final int N = mPendingActivityLaunches.size();
2445        if (N <= 0) {
2446            return;
2447        }
2448        for (int i=0; i<N; i++) {
2449            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2450            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2451                    pal.startFlags, doResume && i == (N-1), null);
2452        }
2453        mPendingActivityLaunches.clear();
2454    }
2455
2456    public final int startActivity(IApplicationThread caller,
2457            Intent intent, String resolvedType, IBinder resultTo,
2458            String resultWho, int requestCode, int startFlags,
2459            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2460        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2461                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2462    }
2463
2464    public final int startActivityAsUser(IApplicationThread caller,
2465            Intent intent, String resolvedType, IBinder resultTo,
2466            String resultWho, int requestCode, int startFlags,
2467            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2468        enforceNotIsolatedCaller("startActivity");
2469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2470                false, true, "startActivity", null);
2471        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2472                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2473                null, null, options, userId);
2474    }
2475
2476    public final WaitResult startActivityAndWait(IApplicationThread caller,
2477            Intent intent, String resolvedType, IBinder resultTo,
2478            String resultWho, int requestCode, int startFlags, String profileFile,
2479            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2480        enforceNotIsolatedCaller("startActivityAndWait");
2481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2482                false, true, "startActivityAndWait", null);
2483        WaitResult res = new WaitResult();
2484        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2485                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2486                res, null, options, UserHandle.getCallingUserId());
2487        return res;
2488    }
2489
2490    public final int startActivityWithConfig(IApplicationThread caller,
2491            Intent intent, String resolvedType, IBinder resultTo,
2492            String resultWho, int requestCode, int startFlags, Configuration config,
2493            Bundle options, int userId) {
2494        enforceNotIsolatedCaller("startActivityWithConfig");
2495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2496                false, true, "startActivityWithConfig", null);
2497        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2498                resultTo, resultWho, requestCode, startFlags,
2499                null, null, null, config, options, userId);
2500        return ret;
2501    }
2502
2503    public int startActivityIntentSender(IApplicationThread caller,
2504            IntentSender intent, Intent fillInIntent, String resolvedType,
2505            IBinder resultTo, String resultWho, int requestCode,
2506            int flagsMask, int flagsValues, Bundle options) {
2507        enforceNotIsolatedCaller("startActivityIntentSender");
2508        // Refuse possible leaked file descriptors
2509        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2510            throw new IllegalArgumentException("File descriptors passed in Intent");
2511        }
2512
2513        IIntentSender sender = intent.getTarget();
2514        if (!(sender instanceof PendingIntentRecord)) {
2515            throw new IllegalArgumentException("Bad PendingIntent object");
2516        }
2517
2518        PendingIntentRecord pir = (PendingIntentRecord)sender;
2519
2520        synchronized (this) {
2521            // If this is coming from the currently resumed activity, it is
2522            // effectively saying that app switches are allowed at this point.
2523            if (mMainStack.mResumedActivity != null
2524                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2525                            Binder.getCallingUid()) {
2526                mAppSwitchesAllowedTime = 0;
2527            }
2528        }
2529        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2530                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2531        return ret;
2532    }
2533
2534    public boolean startNextMatchingActivity(IBinder callingActivity,
2535            Intent intent, Bundle options) {
2536        // Refuse possible leaked file descriptors
2537        if (intent != null && intent.hasFileDescriptors() == true) {
2538            throw new IllegalArgumentException("File descriptors passed in Intent");
2539        }
2540
2541        synchronized (this) {
2542            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2543            if (r == null) {
2544                ActivityOptions.abort(options);
2545                return false;
2546            }
2547            if (r.app == null || r.app.thread == null) {
2548                // The caller is not running...  d'oh!
2549                ActivityOptions.abort(options);
2550                return false;
2551            }
2552            intent = new Intent(intent);
2553            // The caller is not allowed to change the data.
2554            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2555            // And we are resetting to find the next component...
2556            intent.setComponent(null);
2557
2558            ActivityInfo aInfo = null;
2559            try {
2560                List<ResolveInfo> resolves =
2561                    AppGlobals.getPackageManager().queryIntentActivities(
2562                            intent, r.resolvedType,
2563                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2564                            UserHandle.getCallingUserId());
2565
2566                // Look for the original activity in the list...
2567                final int N = resolves != null ? resolves.size() : 0;
2568                for (int i=0; i<N; i++) {
2569                    ResolveInfo rInfo = resolves.get(i);
2570                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2571                            && rInfo.activityInfo.name.equals(r.info.name)) {
2572                        // We found the current one...  the next matching is
2573                        // after it.
2574                        i++;
2575                        if (i<N) {
2576                            aInfo = resolves.get(i).activityInfo;
2577                        }
2578                        break;
2579                    }
2580                }
2581            } catch (RemoteException e) {
2582            }
2583
2584            if (aInfo == null) {
2585                // Nobody who is next!
2586                ActivityOptions.abort(options);
2587                return false;
2588            }
2589
2590            intent.setComponent(new ComponentName(
2591                    aInfo.applicationInfo.packageName, aInfo.name));
2592            intent.setFlags(intent.getFlags()&~(
2593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2596                    Intent.FLAG_ACTIVITY_NEW_TASK));
2597
2598            // Okay now we need to start the new activity, replacing the
2599            // currently running activity.  This is a little tricky because
2600            // we want to start the new one as if the current one is finished,
2601            // but not finish the current one first so that there is no flicker.
2602            // And thus...
2603            final boolean wasFinishing = r.finishing;
2604            r.finishing = true;
2605
2606            // Propagate reply information over to the new activity.
2607            final ActivityRecord resultTo = r.resultTo;
2608            final String resultWho = r.resultWho;
2609            final int requestCode = r.requestCode;
2610            r.resultTo = null;
2611            if (resultTo != null) {
2612                resultTo.removeResultsLocked(r, resultWho, requestCode);
2613            }
2614
2615            final long origId = Binder.clearCallingIdentity();
2616            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2617                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2618                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2619                    options, false, null);
2620            Binder.restoreCallingIdentity(origId);
2621
2622            r.finishing = wasFinishing;
2623            if (res != ActivityManager.START_SUCCESS) {
2624                return false;
2625            }
2626            return true;
2627        }
2628    }
2629
2630    final int startActivityInPackage(int uid,
2631            Intent intent, String resolvedType, IBinder resultTo,
2632            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2633
2634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2635                false, true, "startActivityInPackage", null);
2636
2637        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2638                resultTo, resultWho, requestCode, startFlags,
2639                null, null, null, null, options, userId);
2640        return ret;
2641    }
2642
2643    public final int startActivities(IApplicationThread caller,
2644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2645            int userId) {
2646        enforceNotIsolatedCaller("startActivities");
2647        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2648                false, true, "startActivity", null);
2649        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2650                options, userId);
2651        return ret;
2652    }
2653
2654    final int startActivitiesInPackage(int uid,
2655            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2656            Bundle options, int userId) {
2657
2658        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2659                false, true, "startActivityInPackage", null);
2660        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2661                options, userId);
2662        return ret;
2663    }
2664
2665    final void addRecentTaskLocked(TaskRecord task) {
2666        int N = mRecentTasks.size();
2667        // Quick case: check if the top-most recent task is the same.
2668        if (N > 0 && mRecentTasks.get(0) == task) {
2669            return;
2670        }
2671        // Remove any existing entries that are the same kind of task.
2672        for (int i=0; i<N; i++) {
2673            TaskRecord tr = mRecentTasks.get(i);
2674            if (task.userId == tr.userId
2675                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2676                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2677                mRecentTasks.remove(i);
2678                i--;
2679                N--;
2680                if (task.intent == null) {
2681                    // If the new recent task we are adding is not fully
2682                    // specified, then replace it with the existing recent task.
2683                    task = tr;
2684                }
2685            }
2686        }
2687        if (N >= MAX_RECENT_TASKS) {
2688            mRecentTasks.remove(N-1);
2689        }
2690        mRecentTasks.add(0, task);
2691    }
2692
2693    public void setRequestedOrientation(IBinder token,
2694            int requestedOrientation) {
2695        synchronized (this) {
2696            ActivityRecord r = mMainStack.isInStackLocked(token);
2697            if (r == null) {
2698                return;
2699            }
2700            final long origId = Binder.clearCallingIdentity();
2701            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2702            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2703                    mConfiguration,
2704                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2705            if (config != null) {
2706                r.frozenBeforeDestroy = true;
2707                if (!updateConfigurationLocked(config, r, false, false)) {
2708                    mMainStack.resumeTopActivityLocked(null);
2709                }
2710            }
2711            Binder.restoreCallingIdentity(origId);
2712        }
2713    }
2714
2715    public int getRequestedOrientation(IBinder token) {
2716        synchronized (this) {
2717            ActivityRecord r = mMainStack.isInStackLocked(token);
2718            if (r == null) {
2719                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2720            }
2721            return mWindowManager.getAppOrientation(r.appToken);
2722        }
2723    }
2724
2725    /**
2726     * This is the internal entry point for handling Activity.finish().
2727     *
2728     * @param token The Binder token referencing the Activity we want to finish.
2729     * @param resultCode Result code, if any, from this Activity.
2730     * @param resultData Result data (Intent), if any, from this Activity.
2731     *
2732     * @return Returns true if the activity successfully finished, or false if it is still running.
2733     */
2734    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2735        // Refuse possible leaked file descriptors
2736        if (resultData != null && resultData.hasFileDescriptors() == true) {
2737            throw new IllegalArgumentException("File descriptors passed in Intent");
2738        }
2739
2740        synchronized(this) {
2741            if (mController != null) {
2742                // Find the first activity that is not finishing.
2743                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2744                if (next != null) {
2745                    // ask watcher if this is allowed
2746                    boolean resumeOK = true;
2747                    try {
2748                        resumeOK = mController.activityResuming(next.packageName);
2749                    } catch (RemoteException e) {
2750                        mController = null;
2751                    }
2752
2753                    if (!resumeOK) {
2754                        return false;
2755                    }
2756                }
2757            }
2758            final long origId = Binder.clearCallingIdentity();
2759            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2760                    resultData, "app-request", true);
2761            Binder.restoreCallingIdentity(origId);
2762            return res;
2763        }
2764    }
2765
2766    public final void finishHeavyWeightApp() {
2767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2768                != PackageManager.PERMISSION_GRANTED) {
2769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2770                    + Binder.getCallingPid()
2771                    + ", uid=" + Binder.getCallingUid()
2772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2773            Slog.w(TAG, msg);
2774            throw new SecurityException(msg);
2775        }
2776
2777        synchronized(this) {
2778            if (mHeavyWeightProcess == null) {
2779                return;
2780            }
2781
2782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2783                    mHeavyWeightProcess.activities);
2784            for (int i=0; i<activities.size(); i++) {
2785                ActivityRecord r = activities.get(i);
2786                if (!r.finishing) {
2787                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2788                    if (index >= 0) {
2789                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2790                                null, "finish-heavy", true);
2791                    }
2792                }
2793            }
2794
2795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2796                    mHeavyWeightProcess.userId, 0));
2797            mHeavyWeightProcess = null;
2798        }
2799    }
2800
2801    public void crashApplication(int uid, int initialPid, String packageName,
2802            String message) {
2803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2804                != PackageManager.PERMISSION_GRANTED) {
2805            String msg = "Permission Denial: crashApplication() from pid="
2806                    + Binder.getCallingPid()
2807                    + ", uid=" + Binder.getCallingUid()
2808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2809            Slog.w(TAG, msg);
2810            throw new SecurityException(msg);
2811        }
2812
2813        synchronized(this) {
2814            ProcessRecord proc = null;
2815
2816            // Figure out which process to kill.  We don't trust that initialPid
2817            // still has any relation to current pids, so must scan through the
2818            // list.
2819            synchronized (mPidsSelfLocked) {
2820                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2821                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2822                    if (p.uid != uid) {
2823                        continue;
2824                    }
2825                    if (p.pid == initialPid) {
2826                        proc = p;
2827                        break;
2828                    }
2829                    for (String str : p.pkgList) {
2830                        if (str.equals(packageName)) {
2831                            proc = p;
2832                        }
2833                    }
2834                }
2835            }
2836
2837            if (proc == null) {
2838                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2839                        + " initialPid=" + initialPid
2840                        + " packageName=" + packageName);
2841                return;
2842            }
2843
2844            if (proc.thread != null) {
2845                if (proc.pid == Process.myPid()) {
2846                    Log.w(TAG, "crashApplication: trying to crash self!");
2847                    return;
2848                }
2849                long ident = Binder.clearCallingIdentity();
2850                try {
2851                    proc.thread.scheduleCrash(message);
2852                } catch (RemoteException e) {
2853                }
2854                Binder.restoreCallingIdentity(ident);
2855            }
2856        }
2857    }
2858
2859    public final void finishSubActivity(IBinder token, String resultWho,
2860            int requestCode) {
2861        synchronized(this) {
2862            final long origId = Binder.clearCallingIdentity();
2863            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2864            Binder.restoreCallingIdentity(origId);
2865        }
2866    }
2867
2868    public boolean finishActivityAffinity(IBinder token) {
2869        synchronized(this) {
2870            final long origId = Binder.clearCallingIdentity();
2871            boolean res = mMainStack.finishActivityAffinityLocked(token);
2872            Binder.restoreCallingIdentity(origId);
2873            return res;
2874        }
2875    }
2876
2877    public boolean willActivityBeVisible(IBinder token) {
2878        synchronized(this) {
2879            int i;
2880            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2881                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2882                if (r.appToken == token) {
2883                    return true;
2884                }
2885                if (r.fullscreen && !r.finishing) {
2886                    return false;
2887                }
2888            }
2889            return true;
2890        }
2891    }
2892
2893    public void overridePendingTransition(IBinder token, String packageName,
2894            int enterAnim, int exitAnim) {
2895        synchronized(this) {
2896            ActivityRecord self = mMainStack.isInStackLocked(token);
2897            if (self == null) {
2898                return;
2899            }
2900
2901            final long origId = Binder.clearCallingIdentity();
2902
2903            if (self.state == ActivityState.RESUMED
2904                    || self.state == ActivityState.PAUSING) {
2905                mWindowManager.overridePendingAppTransition(packageName,
2906                        enterAnim, exitAnim, null);
2907            }
2908
2909            Binder.restoreCallingIdentity(origId);
2910        }
2911    }
2912
2913    /**
2914     * Main function for removing an existing process from the activity manager
2915     * as a result of that process going away.  Clears out all connections
2916     * to the process.
2917     */
2918    private final void handleAppDiedLocked(ProcessRecord app,
2919            boolean restarting, boolean allowRestart) {
2920        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2921        if (!restarting) {
2922            mLruProcesses.remove(app);
2923        }
2924
2925        if (mProfileProc == app) {
2926            clearProfilerLocked();
2927        }
2928
2929        // Just in case...
2930        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2931            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2932                    "App died while pausing: " + mMainStack.mPausingActivity);
2933            mMainStack.mPausingActivity = null;
2934        }
2935        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2936            mMainStack.mLastPausedActivity = null;
2937        }
2938
2939        // Remove this application's activities from active lists.
2940        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2941
2942        app.activities.clear();
2943
2944        if (app.instrumentationClass != null) {
2945            Slog.w(TAG, "Crash of app " + app.processName
2946                  + " running instrumentation " + app.instrumentationClass);
2947            Bundle info = new Bundle();
2948            info.putString("shortMsg", "Process crashed.");
2949            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2950        }
2951
2952        if (!restarting) {
2953            if (!mMainStack.resumeTopActivityLocked(null)) {
2954                // If there was nothing to resume, and we are not already
2955                // restarting this process, but there is a visible activity that
2956                // is hosted by the process...  then make sure all visible
2957                // activities are running, taking care of restarting this
2958                // process.
2959                if (hasVisibleActivities) {
2960                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2961                }
2962            }
2963        }
2964    }
2965
2966    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2967        IBinder threadBinder = thread.asBinder();
2968        // Find the application record.
2969        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2970            ProcessRecord rec = mLruProcesses.get(i);
2971            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2972                return i;
2973            }
2974        }
2975        return -1;
2976    }
2977
2978    final ProcessRecord getRecordForAppLocked(
2979            IApplicationThread thread) {
2980        if (thread == null) {
2981            return null;
2982        }
2983
2984        int appIndex = getLRURecordIndexForAppLocked(thread);
2985        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2986    }
2987
2988    final void appDiedLocked(ProcessRecord app, int pid,
2989            IApplicationThread thread) {
2990
2991        mProcDeaths[0]++;
2992
2993        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2994        synchronized (stats) {
2995            stats.noteProcessDiedLocked(app.info.uid, pid);
2996        }
2997
2998        // Clean up already done if the process has been re-started.
2999        if (app.pid == pid && app.thread != null &&
3000                app.thread.asBinder() == thread.asBinder()) {
3001            if (!app.killedBackground) {
3002                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3003                        + ") has died.");
3004            }
3005            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3006            if (DEBUG_CLEANUP) Slog.v(
3007                TAG, "Dying app: " + app + ", pid: " + pid
3008                + ", thread: " + thread.asBinder());
3009            boolean doLowMem = app.instrumentationClass == null;
3010            handleAppDiedLocked(app, false, true);
3011
3012            if (doLowMem) {
3013                // If there are no longer any background processes running,
3014                // and the app that died was not running instrumentation,
3015                // then tell everyone we are now low on memory.
3016                boolean haveBg = false;
3017                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3018                    ProcessRecord rec = mLruProcesses.get(i);
3019                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3020                        haveBg = true;
3021                        break;
3022                    }
3023                }
3024
3025                if (!haveBg) {
3026                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3027                    long now = SystemClock.uptimeMillis();
3028                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3029                        ProcessRecord rec = mLruProcesses.get(i);
3030                        if (rec != app && rec.thread != null &&
3031                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3032                            // The low memory report is overriding any current
3033                            // state for a GC request.  Make sure to do
3034                            // heavy/important/visible/foreground processes first.
3035                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3036                                rec.lastRequestedGc = 0;
3037                            } else {
3038                                rec.lastRequestedGc = rec.lastLowMemory;
3039                            }
3040                            rec.reportLowMemory = true;
3041                            rec.lastLowMemory = now;
3042                            mProcessesToGc.remove(rec);
3043                            addProcessToGcListLocked(rec);
3044                        }
3045                    }
3046                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3047                    scheduleAppGcsLocked();
3048                }
3049            }
3050        } else if (app.pid != pid) {
3051            // A new process has already been started.
3052            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3053                    + ") has died and restarted (pid " + app.pid + ").");
3054            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3055        } else if (DEBUG_PROCESSES) {
3056            Slog.d(TAG, "Received spurious death notification for thread "
3057                    + thread.asBinder());
3058        }
3059    }
3060
3061    /**
3062     * If a stack trace dump file is configured, dump process stack traces.
3063     * @param clearTraces causes the dump file to be erased prior to the new
3064     *    traces being written, if true; when false, the new traces will be
3065     *    appended to any existing file content.
3066     * @param firstPids of dalvik VM processes to dump stack traces for first
3067     * @param lastPids of dalvik VM processes to dump stack traces for last
3068     * @param nativeProcs optional list of native process names to dump stack crawls
3069     * @return file containing stack traces, or null if no dump file is configured
3070     */
3071    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3072            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3073        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3074        if (tracesPath == null || tracesPath.length() == 0) {
3075            return null;
3076        }
3077
3078        File tracesFile = new File(tracesPath);
3079        try {
3080            File tracesDir = tracesFile.getParentFile();
3081            if (!tracesDir.exists()) {
3082                tracesFile.mkdirs();
3083                if (!SELinux.restorecon(tracesDir)) {
3084                    return null;
3085                }
3086            }
3087            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3088
3089            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3090            tracesFile.createNewFile();
3091            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3092        } catch (IOException e) {
3093            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3094            return null;
3095        }
3096
3097        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3098        return tracesFile;
3099    }
3100
3101    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3102            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3103        // Use a FileObserver to detect when traces finish writing.
3104        // The order of traces is considered important to maintain for legibility.
3105        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3106            public synchronized void onEvent(int event, String path) { notify(); }
3107        };
3108
3109        try {
3110            observer.startWatching();
3111
3112            // First collect all of the stacks of the most important pids.
3113            if (firstPids != null) {
3114                try {
3115                    int num = firstPids.size();
3116                    for (int i = 0; i < num; i++) {
3117                        synchronized (observer) {
3118                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3119                            observer.wait(200);  // Wait for write-close, give up after 200msec
3120                        }
3121                    }
3122                } catch (InterruptedException e) {
3123                    Log.wtf(TAG, e);
3124                }
3125            }
3126
3127            // Next measure CPU usage.
3128            if (processStats != null) {
3129                processStats.init();
3130                System.gc();
3131                processStats.update();
3132                try {
3133                    synchronized (processStats) {
3134                        processStats.wait(500); // measure over 1/2 second.
3135                    }
3136                } catch (InterruptedException e) {
3137                }
3138                processStats.update();
3139
3140                // We'll take the stack crawls of just the top apps using CPU.
3141                final int N = processStats.countWorkingStats();
3142                int numProcs = 0;
3143                for (int i=0; i<N && numProcs<5; i++) {
3144                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3145                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3146                        numProcs++;
3147                        try {
3148                            synchronized (observer) {
3149                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3150                                observer.wait(200);  // Wait for write-close, give up after 200msec
3151                            }
3152                        } catch (InterruptedException e) {
3153                            Log.wtf(TAG, e);
3154                        }
3155
3156                    }
3157                }
3158            }
3159
3160        } finally {
3161            observer.stopWatching();
3162        }
3163
3164        if (nativeProcs != null) {
3165            int[] pids = Process.getPidsForCommands(nativeProcs);
3166            if (pids != null) {
3167                for (int pid : pids) {
3168                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3169                }
3170            }
3171        }
3172    }
3173
3174    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3175        if (true || IS_USER_BUILD) {
3176            return;
3177        }
3178        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3179        if (tracesPath == null || tracesPath.length() == 0) {
3180            return;
3181        }
3182
3183        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3184        StrictMode.allowThreadDiskWrites();
3185        try {
3186            final File tracesFile = new File(tracesPath);
3187            final File tracesDir = tracesFile.getParentFile();
3188            final File tracesTmp = new File(tracesDir, "__tmp__");
3189            try {
3190                if (!tracesDir.exists()) {
3191                    tracesFile.mkdirs();
3192                    if (!SELinux.restorecon(tracesDir.getPath())) {
3193                        return;
3194                    }
3195                }
3196                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3197
3198                if (tracesFile.exists()) {
3199                    tracesTmp.delete();
3200                    tracesFile.renameTo(tracesTmp);
3201                }
3202                StringBuilder sb = new StringBuilder();
3203                Time tobj = new Time();
3204                tobj.set(System.currentTimeMillis());
3205                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3206                sb.append(": ");
3207                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3208                sb.append(" since ");
3209                sb.append(msg);
3210                FileOutputStream fos = new FileOutputStream(tracesFile);
3211                fos.write(sb.toString().getBytes());
3212                if (app == null) {
3213                    fos.write("\n*** No application process!".getBytes());
3214                }
3215                fos.close();
3216                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3217            } catch (IOException e) {
3218                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3219                return;
3220            }
3221
3222            if (app != null) {
3223                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3224                firstPids.add(app.pid);
3225                dumpStackTraces(tracesPath, firstPids, null, null, null);
3226            }
3227
3228            File lastTracesFile = null;
3229            File curTracesFile = null;
3230            for (int i=9; i>=0; i--) {
3231                String name = String.format("slow%02d.txt", i);
3232                curTracesFile = new File(tracesDir, name);
3233                if (curTracesFile.exists()) {
3234                    if (lastTracesFile != null) {
3235                        curTracesFile.renameTo(lastTracesFile);
3236                    } else {
3237                        curTracesFile.delete();
3238                    }
3239                }
3240                lastTracesFile = curTracesFile;
3241            }
3242            tracesFile.renameTo(curTracesFile);
3243            if (tracesTmp.exists()) {
3244                tracesTmp.renameTo(tracesFile);
3245            }
3246        } finally {
3247            StrictMode.setThreadPolicy(oldPolicy);
3248        }
3249    }
3250
3251    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3252            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3253        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3254        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3255
3256        if (mController != null) {
3257            try {
3258                // 0 == continue, -1 = kill process immediately
3259                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3260                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3261            } catch (RemoteException e) {
3262                mController = null;
3263            }
3264        }
3265
3266        long anrTime = SystemClock.uptimeMillis();
3267        if (MONITOR_CPU_USAGE) {
3268            updateCpuStatsNow();
3269        }
3270
3271        synchronized (this) {
3272            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3273            if (mShuttingDown) {
3274                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3275                return;
3276            } else if (app.notResponding) {
3277                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3278                return;
3279            } else if (app.crashing) {
3280                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3281                return;
3282            }
3283
3284            // In case we come through here for the same app before completing
3285            // this one, mark as anring now so we will bail out.
3286            app.notResponding = true;
3287
3288            // Log the ANR to the event log.
3289            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3290                    app.processName, app.info.flags, annotation);
3291
3292            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3293            firstPids.add(app.pid);
3294
3295            int parentPid = app.pid;
3296            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3297            if (parentPid != app.pid) firstPids.add(parentPid);
3298
3299            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3300
3301            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3302                ProcessRecord r = mLruProcesses.get(i);
3303                if (r != null && r.thread != null) {
3304                    int pid = r.pid;
3305                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3306                        if (r.persistent) {
3307                            firstPids.add(pid);
3308                        } else {
3309                            lastPids.put(pid, Boolean.TRUE);
3310                        }
3311                    }
3312                }
3313            }
3314        }
3315
3316        // Log the ANR to the main log.
3317        StringBuilder info = new StringBuilder();
3318        info.setLength(0);
3319        info.append("ANR in ").append(app.processName);
3320        if (activity != null && activity.shortComponentName != null) {
3321            info.append(" (").append(activity.shortComponentName).append(")");
3322        }
3323        info.append("\n");
3324        if (annotation != null) {
3325            info.append("Reason: ").append(annotation).append("\n");
3326        }
3327        if (parent != null && parent != activity) {
3328            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3329        }
3330
3331        final ProcessStats processStats = new ProcessStats(true);
3332
3333        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3334
3335        String cpuInfo = null;
3336        if (MONITOR_CPU_USAGE) {
3337            updateCpuStatsNow();
3338            synchronized (mProcessStatsThread) {
3339                cpuInfo = mProcessStats.printCurrentState(anrTime);
3340            }
3341            info.append(processStats.printCurrentLoad());
3342            info.append(cpuInfo);
3343        }
3344
3345        info.append(processStats.printCurrentState(anrTime));
3346
3347        Slog.e(TAG, info.toString());
3348        if (tracesFile == null) {
3349            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3350            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3351        }
3352
3353        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3354                cpuInfo, tracesFile, null);
3355
3356        if (mController != null) {
3357            try {
3358                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3359                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3360                if (res != 0) {
3361                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3362                    return;
3363                }
3364            } catch (RemoteException e) {
3365                mController = null;
3366            }
3367        }
3368
3369        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3370        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3371                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3372
3373        synchronized (this) {
3374            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3375                Slog.w(TAG, "Killing " + app + ": background ANR");
3376                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3377                        app.processName, app.setAdj, "background ANR");
3378                Process.killProcessQuiet(app.pid);
3379                return;
3380            }
3381
3382            // Set the app's notResponding state, and look up the errorReportReceiver
3383            makeAppNotRespondingLocked(app,
3384                    activity != null ? activity.shortComponentName : null,
3385                    annotation != null ? "ANR " + annotation : "ANR",
3386                    info.toString());
3387
3388            // Bring up the infamous App Not Responding dialog
3389            Message msg = Message.obtain();
3390            HashMap map = new HashMap();
3391            msg.what = SHOW_NOT_RESPONDING_MSG;
3392            msg.obj = map;
3393            msg.arg1 = aboveSystem ? 1 : 0;
3394            map.put("app", app);
3395            if (activity != null) {
3396                map.put("activity", activity);
3397            }
3398
3399            mHandler.sendMessage(msg);
3400        }
3401    }
3402
3403    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3404        if (!mLaunchWarningShown) {
3405            mLaunchWarningShown = true;
3406            mHandler.post(new Runnable() {
3407                @Override
3408                public void run() {
3409                    synchronized (ActivityManagerService.this) {
3410                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3411                        d.show();
3412                        mHandler.postDelayed(new Runnable() {
3413                            @Override
3414                            public void run() {
3415                                synchronized (ActivityManagerService.this) {
3416                                    d.dismiss();
3417                                    mLaunchWarningShown = false;
3418                                }
3419                            }
3420                        }, 4000);
3421                    }
3422                }
3423            });
3424        }
3425    }
3426
3427    public boolean clearApplicationUserData(final String packageName,
3428            final IPackageDataObserver observer, int userId) {
3429        enforceNotIsolatedCaller("clearApplicationUserData");
3430        int uid = Binder.getCallingUid();
3431        int pid = Binder.getCallingPid();
3432        userId = handleIncomingUser(pid, uid,
3433                userId, false, true, "clearApplicationUserData", null);
3434        long callingId = Binder.clearCallingIdentity();
3435        try {
3436            IPackageManager pm = AppGlobals.getPackageManager();
3437            int pkgUid = -1;
3438            synchronized(this) {
3439                try {
3440                    pkgUid = pm.getPackageUid(packageName, userId);
3441                } catch (RemoteException e) {
3442                }
3443                if (pkgUid == -1) {
3444                    Slog.w(TAG, "Invalid packageName:" + packageName);
3445                    return false;
3446                }
3447                if (uid == pkgUid || checkComponentPermission(
3448                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3449                        pid, uid, -1, true)
3450                        == PackageManager.PERMISSION_GRANTED) {
3451                    forceStopPackageLocked(packageName, pkgUid);
3452                } else {
3453                    throw new SecurityException(pid+" does not have permission:"+
3454                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3455                                    "for process:"+packageName);
3456                }
3457            }
3458
3459            try {
3460                //clear application user data
3461                pm.clearApplicationUserData(packageName, observer, userId);
3462                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3463                        Uri.fromParts("package", packageName, null));
3464                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3465                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3466                        null, null, 0, null, null, null, false, false, userId);
3467            } catch (RemoteException e) {
3468            }
3469        } finally {
3470            Binder.restoreCallingIdentity(callingId);
3471        }
3472        return true;
3473    }
3474
3475    public void killBackgroundProcesses(final String packageName, int userId) {
3476        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3477                != PackageManager.PERMISSION_GRANTED &&
3478                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3479                        != PackageManager.PERMISSION_GRANTED) {
3480            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3481                    + Binder.getCallingPid()
3482                    + ", uid=" + Binder.getCallingUid()
3483                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3484            Slog.w(TAG, msg);
3485            throw new SecurityException(msg);
3486        }
3487
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3489                userId, true, true, "killBackgroundProcesses", null);
3490        long callingId = Binder.clearCallingIdentity();
3491        try {
3492            IPackageManager pm = AppGlobals.getPackageManager();
3493            synchronized(this) {
3494                int appId = -1;
3495                try {
3496                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3497                } catch (RemoteException e) {
3498                }
3499                if (appId == -1) {
3500                    Slog.w(TAG, "Invalid packageName: " + packageName);
3501                    return;
3502                }
3503                killPackageProcessesLocked(packageName, appId, userId,
3504                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3505            }
3506        } finally {
3507            Binder.restoreCallingIdentity(callingId);
3508        }
3509    }
3510
3511    public void killAllBackgroundProcesses() {
3512        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521
3522        long callingId = Binder.clearCallingIdentity();
3523        try {
3524            synchronized(this) {
3525                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3526                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3527                    final int NA = apps.size();
3528                    for (int ia=0; ia<NA; ia++) {
3529                        ProcessRecord app = apps.valueAt(ia);
3530                        if (app.persistent) {
3531                            // we don't kill persistent processes
3532                            continue;
3533                        }
3534                        if (app.removed) {
3535                            procs.add(app);
3536                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3537                            app.removed = true;
3538                            procs.add(app);
3539                        }
3540                    }
3541                }
3542
3543                int N = procs.size();
3544                for (int i=0; i<N; i++) {
3545                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3546                }
3547            }
3548        } finally {
3549            Binder.restoreCallingIdentity(callingId);
3550        }
3551    }
3552
3553    public void forceStopPackage(final String packageName, int userId) {
3554        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3555                != PackageManager.PERMISSION_GRANTED) {
3556            String msg = "Permission Denial: forceStopPackage() from pid="
3557                    + Binder.getCallingPid()
3558                    + ", uid=" + Binder.getCallingUid()
3559                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3560            Slog.w(TAG, msg);
3561            throw new SecurityException(msg);
3562        }
3563        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3564                userId, true, true, "forceStopPackage", null);
3565        long callingId = Binder.clearCallingIdentity();
3566        try {
3567            IPackageManager pm = AppGlobals.getPackageManager();
3568            synchronized(this) {
3569                int[] users = userId == UserHandle.USER_ALL
3570                        ? getUsersLocked() : new int[] { userId };
3571                for (int user : users) {
3572                    int pkgUid = -1;
3573                    try {
3574                        pkgUid = pm.getPackageUid(packageName, user);
3575                    } catch (RemoteException e) {
3576                    }
3577                    if (pkgUid == -1) {
3578                        Slog.w(TAG, "Invalid packageName: " + packageName);
3579                        continue;
3580                    }
3581                    try {
3582                        pm.setPackageStoppedState(packageName, true, user);
3583                    } catch (RemoteException e) {
3584                    } catch (IllegalArgumentException e) {
3585                        Slog.w(TAG, "Failed trying to unstop package "
3586                                + packageName + ": " + e);
3587                    }
3588                    if (isUserRunningLocked(user, false)) {
3589                        forceStopPackageLocked(packageName, pkgUid);
3590                    }
3591                }
3592            }
3593        } finally {
3594            Binder.restoreCallingIdentity(callingId);
3595        }
3596    }
3597
3598    /*
3599     * The pkg name and app id have to be specified.
3600     */
3601    public void killApplicationWithAppId(String pkg, int appid) {
3602        if (pkg == null) {
3603            return;
3604        }
3605        // Make sure the uid is valid.
3606        if (appid < 0) {
3607            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3608            return;
3609        }
3610        int callerUid = Binder.getCallingUid();
3611        // Only the system server can kill an application
3612        if (callerUid == Process.SYSTEM_UID) {
3613            // Post an aysnc message to kill the application
3614            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3615            msg.arg1 = appid;
3616            msg.arg2 = 0;
3617            msg.obj = pkg;
3618            mHandler.sendMessage(msg);
3619        } else {
3620            throw new SecurityException(callerUid + " cannot kill pkg: " +
3621                    pkg);
3622        }
3623    }
3624
3625    public void closeSystemDialogs(String reason) {
3626        enforceNotIsolatedCaller("closeSystemDialogs");
3627
3628        final int pid = Binder.getCallingPid();
3629        final int uid = Binder.getCallingUid();
3630        final long origId = Binder.clearCallingIdentity();
3631        try {
3632            synchronized (this) {
3633                // Only allow this from foreground processes, so that background
3634                // applications can't abuse it to prevent system UI from being shown.
3635                if (uid >= Process.FIRST_APPLICATION_UID) {
3636                    ProcessRecord proc;
3637                    synchronized (mPidsSelfLocked) {
3638                        proc = mPidsSelfLocked.get(pid);
3639                    }
3640                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3641                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3642                                + " from background process " + proc);
3643                        return;
3644                    }
3645                }
3646                closeSystemDialogsLocked(reason);
3647            }
3648        } finally {
3649            Binder.restoreCallingIdentity(origId);
3650        }
3651    }
3652
3653    void closeSystemDialogsLocked(String reason) {
3654        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3655        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3656                | Intent.FLAG_RECEIVER_FOREGROUND);
3657        if (reason != null) {
3658            intent.putExtra("reason", reason);
3659        }
3660        mWindowManager.closeSystemDialogs(reason);
3661
3662        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3663            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3664            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3665                r.stack.finishActivityLocked(r, i,
3666                        Activity.RESULT_CANCELED, null, "close-sys", true);
3667            }
3668        }
3669
3670        broadcastIntentLocked(null, null, intent, null,
3671                null, 0, null, null, null, false, false, -1,
3672                Process.SYSTEM_UID, UserHandle.USER_ALL);
3673    }
3674
3675    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3676            throws RemoteException {
3677        enforceNotIsolatedCaller("getProcessMemoryInfo");
3678        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3679        for (int i=pids.length-1; i>=0; i--) {
3680            infos[i] = new Debug.MemoryInfo();
3681            Debug.getMemoryInfo(pids[i], infos[i]);
3682        }
3683        return infos;
3684    }
3685
3686    public long[] getProcessPss(int[] pids) throws RemoteException {
3687        enforceNotIsolatedCaller("getProcessPss");
3688        long[] pss = new long[pids.length];
3689        for (int i=pids.length-1; i>=0; i--) {
3690            pss[i] = Debug.getPss(pids[i]);
3691        }
3692        return pss;
3693    }
3694
3695    public void killApplicationProcess(String processName, int uid) {
3696        if (processName == null) {
3697            return;
3698        }
3699
3700        int callerUid = Binder.getCallingUid();
3701        // Only the system server can kill an application
3702        if (callerUid == Process.SYSTEM_UID) {
3703            synchronized (this) {
3704                ProcessRecord app = getProcessRecordLocked(processName, uid);
3705                if (app != null && app.thread != null) {
3706                    try {
3707                        app.thread.scheduleSuicide();
3708                    } catch (RemoteException e) {
3709                        // If the other end already died, then our work here is done.
3710                    }
3711                } else {
3712                    Slog.w(TAG, "Process/uid not found attempting kill of "
3713                            + processName + " / " + uid);
3714                }
3715            }
3716        } else {
3717            throw new SecurityException(callerUid + " cannot kill app process: " +
3718                    processName);
3719        }
3720    }
3721
3722    private void forceStopPackageLocked(final String packageName, int uid) {
3723        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3724                false, true, false, UserHandle.getUserId(uid));
3725        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3726                Uri.fromParts("package", packageName, null));
3727        if (!mProcessesReady) {
3728            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3729                    | Intent.FLAG_RECEIVER_FOREGROUND);
3730        }
3731        intent.putExtra(Intent.EXTRA_UID, uid);
3732        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3733        broadcastIntentLocked(null, null, intent,
3734                null, null, 0, null, null, null,
3735                false, false,
3736                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3737    }
3738
3739    private void forceStopUserLocked(int userId) {
3740        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3741        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3743                | Intent.FLAG_RECEIVER_FOREGROUND);
3744        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3745        broadcastIntentLocked(null, null, intent,
3746                null, null, 0, null, null, null,
3747                false, false,
3748                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3749    }
3750
3751    private final boolean killPackageProcessesLocked(String packageName, int appId,
3752            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3753            boolean doit, boolean evenPersistent, String reason) {
3754        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3755
3756        // Remove all processes this package may have touched: all with the
3757        // same UID (except for the system or root user), and all whose name
3758        // matches the package name.
3759        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3760        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3761            final int NA = apps.size();
3762            for (int ia=0; ia<NA; ia++) {
3763                ProcessRecord app = apps.valueAt(ia);
3764                if (app.persistent && !evenPersistent) {
3765                    // we don't kill persistent processes
3766                    continue;
3767                }
3768                if (app.removed) {
3769                    if (doit) {
3770                        procs.add(app);
3771                    }
3772                    continue;
3773                }
3774
3775                // Skip process if it doesn't meet our oom adj requirement.
3776                if (app.setAdj < minOomAdj) {
3777                    continue;
3778                }
3779
3780                // If no package is specified, we call all processes under the
3781                // give user id.
3782                if (packageName == null) {
3783                    if (app.userId != userId) {
3784                        continue;
3785                    }
3786                // Package has been specified, we want to hit all processes
3787                // that match it.  We need to qualify this by the processes
3788                // that are running under the specified app and user ID.
3789                } else {
3790                    if (UserHandle.getAppId(app.uid) != appId) {
3791                        continue;
3792                    }
3793                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3794                        continue;
3795                    }
3796                    if (!app.pkgList.contains(packageName)) {
3797                        continue;
3798                    }
3799                }
3800
3801                // Process has passed all conditions, kill it!
3802                if (!doit) {
3803                    return true;
3804                }
3805                app.removed = true;
3806                procs.add(app);
3807            }
3808        }
3809
3810        int N = procs.size();
3811        for (int i=0; i<N; i++) {
3812            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3813        }
3814        return N > 0;
3815    }
3816
3817    private final boolean forceStopPackageLocked(String name, int appId,
3818            boolean callerWillRestart, boolean purgeCache, boolean doit,
3819            boolean evenPersistent, int userId) {
3820        int i;
3821        int N;
3822
3823        if (userId == UserHandle.USER_ALL && name == null) {
3824            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3825        }
3826
3827        if (appId < 0 && name != null) {
3828            try {
3829                appId = UserHandle.getAppId(
3830                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3831            } catch (RemoteException e) {
3832            }
3833        }
3834
3835        if (doit) {
3836            if (name != null) {
3837                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3838                        + " user=" + userId);
3839            } else {
3840                Slog.i(TAG, "Force stopping user " + userId);
3841            }
3842
3843            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3844            while (badApps.hasNext()) {
3845                SparseArray<Long> ba = badApps.next();
3846                for (i=ba.size()-1; i>=0; i--) {
3847                    boolean remove = false;
3848                    final int entUid = ba.keyAt(i);
3849                    if (name != null) {
3850                        if (userId == UserHandle.USER_ALL) {
3851                            if (UserHandle.getAppId(entUid) == appId) {
3852                                remove = true;
3853                            }
3854                        } else {
3855                            if (entUid == UserHandle.getUid(userId, appId)) {
3856                                remove = true;
3857                            }
3858                        }
3859                    } else if (UserHandle.getUserId(entUid) == userId) {
3860                        remove = true;
3861                    }
3862                    if (remove) {
3863                        ba.removeAt(i);
3864                    }
3865                }
3866                if (ba.size() == 0) {
3867                    badApps.remove();
3868                }
3869            }
3870        }
3871
3872        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3873                -100, callerWillRestart, false, doit, evenPersistent,
3874                name == null ? ("force stop user " + userId) : ("force stop " + name));
3875
3876        TaskRecord lastTask = null;
3877        for (i=0; i<mMainStack.mHistory.size(); i++) {
3878            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3879            final boolean samePackage = r.packageName.equals(name)
3880                    || (name == null && r.userId == userId);
3881            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3882                    && (samePackage || r.task == lastTask)
3883                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3884                if (!doit) {
3885                    if (r.finishing) {
3886                        // If this activity is just finishing, then it is not
3887                        // interesting as far as something to stop.
3888                        continue;
3889                    }
3890                    return true;
3891                }
3892                didSomething = true;
3893                Slog.i(TAG, "  Force finishing activity " + r);
3894                if (samePackage) {
3895                    if (r.app != null) {
3896                        r.app.removed = true;
3897                    }
3898                    r.app = null;
3899                }
3900                lastTask = r.task;
3901                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3902                        null, "force-stop", true)) {
3903                    i--;
3904                }
3905            }
3906        }
3907
3908        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3909            if (!doit) {
3910                return true;
3911            }
3912            didSomething = true;
3913        }
3914
3915        if (name == null) {
3916            // Remove all sticky broadcasts from this user.
3917            mStickyBroadcasts.remove(userId);
3918        }
3919
3920        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3921        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3922                userId, providers)) {
3923            if (!doit) {
3924                return true;
3925            }
3926            didSomething = true;
3927        }
3928        N = providers.size();
3929        for (i=0; i<N; i++) {
3930            removeDyingProviderLocked(null, providers.get(i), true);
3931        }
3932
3933        if (name == null) {
3934            // Remove pending intents.  For now we only do this when force
3935            // stopping users, because we have some problems when doing this
3936            // for packages -- app widgets are not currently cleaned up for
3937            // such packages, so they can be left with bad pending intents.
3938            if (mIntentSenderRecords.size() > 0) {
3939                Iterator<WeakReference<PendingIntentRecord>> it
3940                        = mIntentSenderRecords.values().iterator();
3941                while (it.hasNext()) {
3942                    WeakReference<PendingIntentRecord> wpir = it.next();
3943                    if (wpir == null) {
3944                        it.remove();
3945                        continue;
3946                    }
3947                    PendingIntentRecord pir = wpir.get();
3948                    if (pir == null) {
3949                        it.remove();
3950                        continue;
3951                    }
3952                    if (name == null) {
3953                        // Stopping user, remove all objects for the user.
3954                        if (pir.key.userId != userId) {
3955                            // Not the same user, skip it.
3956                            continue;
3957                        }
3958                    } else {
3959                        if (UserHandle.getAppId(pir.uid) != appId) {
3960                            // Different app id, skip it.
3961                            continue;
3962                        }
3963                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3964                            // Different user, skip it.
3965                            continue;
3966                        }
3967                        if (!pir.key.packageName.equals(name)) {
3968                            // Different package, skip it.
3969                            continue;
3970                        }
3971                    }
3972                    if (!doit) {
3973                        return true;
3974                    }
3975                    didSomething = true;
3976                    it.remove();
3977                    pir.canceled = true;
3978                    if (pir.key.activity != null) {
3979                        pir.key.activity.pendingResults.remove(pir.ref);
3980                    }
3981                }
3982            }
3983        }
3984
3985        if (doit) {
3986            if (purgeCache && name != null) {
3987                AttributeCache ac = AttributeCache.instance();
3988                if (ac != null) {
3989                    ac.removePackage(name);
3990                }
3991            }
3992            if (mBooted) {
3993                mMainStack.resumeTopActivityLocked(null);
3994                mMainStack.scheduleIdleLocked();
3995            }
3996        }
3997
3998        return didSomething;
3999    }
4000
4001    private final boolean removeProcessLocked(ProcessRecord app,
4002            boolean callerWillRestart, boolean allowRestart, String reason) {
4003        final String name = app.processName;
4004        final int uid = app.uid;
4005        if (DEBUG_PROCESSES) Slog.d(
4006            TAG, "Force removing proc " + app.toShortString() + " (" + name
4007            + "/" + uid + ")");
4008
4009        mProcessNames.remove(name, uid);
4010        mIsolatedProcesses.remove(app.uid);
4011        if (mHeavyWeightProcess == app) {
4012            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4013                    mHeavyWeightProcess.userId, 0));
4014            mHeavyWeightProcess = null;
4015        }
4016        boolean needRestart = false;
4017        if (app.pid > 0 && app.pid != MY_PID) {
4018            int pid = app.pid;
4019            synchronized (mPidsSelfLocked) {
4020                mPidsSelfLocked.remove(pid);
4021                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4022            }
4023            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4024            handleAppDiedLocked(app, true, allowRestart);
4025            mLruProcesses.remove(app);
4026            Process.killProcessQuiet(pid);
4027
4028            if (app.persistent && !app.isolated) {
4029                if (!callerWillRestart) {
4030                    addAppLocked(app.info, false);
4031                } else {
4032                    needRestart = true;
4033                }
4034            }
4035        } else {
4036            mRemovedProcesses.add(app);
4037        }
4038
4039        return needRestart;
4040    }
4041
4042    private final void processStartTimedOutLocked(ProcessRecord app) {
4043        final int pid = app.pid;
4044        boolean gone = false;
4045        synchronized (mPidsSelfLocked) {
4046            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4047            if (knownApp != null && knownApp.thread == null) {
4048                mPidsSelfLocked.remove(pid);
4049                gone = true;
4050            }
4051        }
4052
4053        if (gone) {
4054            Slog.w(TAG, "Process " + app + " failed to attach");
4055            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4056                    pid, app.uid, app.processName);
4057            mProcessNames.remove(app.processName, app.uid);
4058            mIsolatedProcesses.remove(app.uid);
4059            if (mHeavyWeightProcess == app) {
4060                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4061                        mHeavyWeightProcess.userId, 0));
4062                mHeavyWeightProcess = null;
4063            }
4064            // Take care of any launching providers waiting for this process.
4065            checkAppInLaunchingProvidersLocked(app, true);
4066            // Take care of any services that are waiting for the process.
4067            mServices.processStartTimedOutLocked(app);
4068            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4069                    app.processName, app.setAdj, "start timeout");
4070            Process.killProcessQuiet(pid);
4071            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4072                Slog.w(TAG, "Unattached app died before backup, skipping");
4073                try {
4074                    IBackupManager bm = IBackupManager.Stub.asInterface(
4075                            ServiceManager.getService(Context.BACKUP_SERVICE));
4076                    bm.agentDisconnected(app.info.packageName);
4077                } catch (RemoteException e) {
4078                    // Can't happen; the backup manager is local
4079                }
4080            }
4081            if (isPendingBroadcastProcessLocked(pid)) {
4082                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4083                skipPendingBroadcastLocked(pid);
4084            }
4085        } else {
4086            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4087        }
4088    }
4089
4090    private final boolean attachApplicationLocked(IApplicationThread thread,
4091            int pid) {
4092
4093        // Find the application record that is being attached...  either via
4094        // the pid if we are running in multiple processes, or just pull the
4095        // next app record if we are emulating process with anonymous threads.
4096        ProcessRecord app;
4097        if (pid != MY_PID && pid >= 0) {
4098            synchronized (mPidsSelfLocked) {
4099                app = mPidsSelfLocked.get(pid);
4100            }
4101        } else {
4102            app = null;
4103        }
4104
4105        if (app == null) {
4106            Slog.w(TAG, "No pending application record for pid " + pid
4107                    + " (IApplicationThread " + thread + "); dropping process");
4108            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4109            if (pid > 0 && pid != MY_PID) {
4110                Process.killProcessQuiet(pid);
4111            } else {
4112                try {
4113                    thread.scheduleExit();
4114                } catch (Exception e) {
4115                    // Ignore exceptions.
4116                }
4117            }
4118            return false;
4119        }
4120
4121        // If this application record is still attached to a previous
4122        // process, clean it up now.
4123        if (app.thread != null) {
4124            handleAppDiedLocked(app, true, true);
4125        }
4126
4127        // Tell the process all about itself.
4128
4129        if (localLOGV) Slog.v(
4130                TAG, "Binding process pid " + pid + " to record " + app);
4131
4132        String processName = app.processName;
4133        try {
4134            AppDeathRecipient adr = new AppDeathRecipient(
4135                    app, pid, thread);
4136            thread.asBinder().linkToDeath(adr, 0);
4137            app.deathRecipient = adr;
4138        } catch (RemoteException e) {
4139            app.resetPackageList();
4140            startProcessLocked(app, "link fail", processName);
4141            return false;
4142        }
4143
4144        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4145
4146        app.thread = thread;
4147        app.curAdj = app.setAdj = -100;
4148        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4149        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4150        app.forcingToForeground = null;
4151        app.foregroundServices = false;
4152        app.hasShownUi = false;
4153        app.debugging = false;
4154
4155        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4156
4157        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4158        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4159
4160        if (!normalMode) {
4161            Slog.i(TAG, "Launching preboot mode app: " + app);
4162        }
4163
4164        if (localLOGV) Slog.v(
4165            TAG, "New app record " + app
4166            + " thread=" + thread.asBinder() + " pid=" + pid);
4167        try {
4168            int testMode = IApplicationThread.DEBUG_OFF;
4169            if (mDebugApp != null && mDebugApp.equals(processName)) {
4170                testMode = mWaitForDebugger
4171                    ? IApplicationThread.DEBUG_WAIT
4172                    : IApplicationThread.DEBUG_ON;
4173                app.debugging = true;
4174                if (mDebugTransient) {
4175                    mDebugApp = mOrigDebugApp;
4176                    mWaitForDebugger = mOrigWaitForDebugger;
4177                }
4178            }
4179            String profileFile = app.instrumentationProfileFile;
4180            ParcelFileDescriptor profileFd = null;
4181            boolean profileAutoStop = false;
4182            if (mProfileApp != null && mProfileApp.equals(processName)) {
4183                mProfileProc = app;
4184                profileFile = mProfileFile;
4185                profileFd = mProfileFd;
4186                profileAutoStop = mAutoStopProfiler;
4187            }
4188            boolean enableOpenGlTrace = false;
4189            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4190                enableOpenGlTrace = true;
4191                mOpenGlTraceApp = null;
4192            }
4193
4194            // If the app is being launched for restore or full backup, set it up specially
4195            boolean isRestrictedBackupMode = false;
4196            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4197                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4198                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4199                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4200            }
4201
4202            ensurePackageDexOpt(app.instrumentationInfo != null
4203                    ? app.instrumentationInfo.packageName
4204                    : app.info.packageName);
4205            if (app.instrumentationClass != null) {
4206                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4207            }
4208            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4209                    + processName + " with config " + mConfiguration);
4210            ApplicationInfo appInfo = app.instrumentationInfo != null
4211                    ? app.instrumentationInfo : app.info;
4212            app.compat = compatibilityInfoForPackageLocked(appInfo);
4213            if (profileFd != null) {
4214                profileFd = profileFd.dup();
4215            }
4216            thread.bindApplication(processName, appInfo, providers,
4217                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4218                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4219                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4220                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4221                    mCoreSettingsObserver.getCoreSettingsLocked());
4222            updateLruProcessLocked(app, false);
4223            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4224        } catch (Exception e) {
4225            // todo: Yikes!  What should we do?  For now we will try to
4226            // start another process, but that could easily get us in
4227            // an infinite loop of restarting processes...
4228            Slog.w(TAG, "Exception thrown during bind!", e);
4229
4230            app.resetPackageList();
4231            app.unlinkDeathRecipient();
4232            startProcessLocked(app, "bind fail", processName);
4233            return false;
4234        }
4235
4236        // Remove this record from the list of starting applications.
4237        mPersistentStartingProcesses.remove(app);
4238        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4239                "Attach application locked removing on hold: " + app);
4240        mProcessesOnHold.remove(app);
4241
4242        boolean badApp = false;
4243        boolean didSomething = false;
4244
4245        // See if the top visible activity is waiting to run in this process...
4246        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4247        if (hr != null && normalMode) {
4248            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4249                    && processName.equals(hr.processName)) {
4250                try {
4251                    if (mHeadless) {
4252                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4253                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4254                        didSomething = true;
4255                    }
4256                } catch (Exception e) {
4257                    Slog.w(TAG, "Exception in new application when starting activity "
4258                          + hr.intent.getComponent().flattenToShortString(), e);
4259                    badApp = true;
4260                }
4261            } else {
4262                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4263            }
4264        }
4265
4266        // Find any services that should be running in this process...
4267        if (!badApp) {
4268            try {
4269                didSomething |= mServices.attachApplicationLocked(app, processName);
4270            } catch (Exception e) {
4271                badApp = true;
4272            }
4273        }
4274
4275        // Check if a next-broadcast receiver is in this process...
4276        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4277            try {
4278                didSomething = sendPendingBroadcastsLocked(app);
4279            } catch (Exception e) {
4280                // If the app died trying to launch the receiver we declare it 'bad'
4281                badApp = true;
4282            }
4283        }
4284
4285        // Check whether the next backup agent is in this process...
4286        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4287            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4288            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4289            try {
4290                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4291                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4292                        mBackupTarget.backupMode);
4293            } catch (Exception e) {
4294                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4295                e.printStackTrace();
4296            }
4297        }
4298
4299        if (badApp) {
4300            // todo: Also need to kill application to deal with all
4301            // kinds of exceptions.
4302            handleAppDiedLocked(app, false, true);
4303            return false;
4304        }
4305
4306        if (!didSomething) {
4307            updateOomAdjLocked();
4308        }
4309
4310        return true;
4311    }
4312
4313    public final void attachApplication(IApplicationThread thread) {
4314        synchronized (this) {
4315            int callingPid = Binder.getCallingPid();
4316            final long origId = Binder.clearCallingIdentity();
4317            attachApplicationLocked(thread, callingPid);
4318            Binder.restoreCallingIdentity(origId);
4319        }
4320    }
4321
4322    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4323        final long origId = Binder.clearCallingIdentity();
4324        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4325        if (stopProfiling) {
4326            synchronized (this) {
4327                if (mProfileProc == r.app) {
4328                    if (mProfileFd != null) {
4329                        try {
4330                            mProfileFd.close();
4331                        } catch (IOException e) {
4332                        }
4333                        clearProfilerLocked();
4334                    }
4335                }
4336            }
4337        }
4338        Binder.restoreCallingIdentity(origId);
4339    }
4340
4341    void enableScreenAfterBoot() {
4342        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4343                SystemClock.uptimeMillis());
4344        mWindowManager.enableScreenAfterBoot();
4345
4346        synchronized (this) {
4347            updateEventDispatchingLocked();
4348        }
4349    }
4350
4351    public void showBootMessage(final CharSequence msg, final boolean always) {
4352        enforceNotIsolatedCaller("showBootMessage");
4353        mWindowManager.showBootMessage(msg, always);
4354    }
4355
4356    public void dismissKeyguardOnNextActivity() {
4357        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4358        final long token = Binder.clearCallingIdentity();
4359        try {
4360            synchronized (this) {
4361                if (mLockScreenShown) {
4362                    mLockScreenShown = false;
4363                    comeOutOfSleepIfNeededLocked();
4364                }
4365                mMainStack.dismissKeyguardOnNextActivityLocked();
4366            }
4367        } finally {
4368            Binder.restoreCallingIdentity(token);
4369        }
4370    }
4371
4372    final void finishBooting() {
4373        IntentFilter pkgFilter = new IntentFilter();
4374        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4375        pkgFilter.addDataScheme("package");
4376        mContext.registerReceiver(new BroadcastReceiver() {
4377            @Override
4378            public void onReceive(Context context, Intent intent) {
4379                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4380                if (pkgs != null) {
4381                    for (String pkg : pkgs) {
4382                        synchronized (ActivityManagerService.this) {
4383                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4384                                setResultCode(Activity.RESULT_OK);
4385                                return;
4386                            }
4387                        }
4388                    }
4389                }
4390            }
4391        }, pkgFilter);
4392
4393        synchronized (this) {
4394            // Ensure that any processes we had put on hold are now started
4395            // up.
4396            final int NP = mProcessesOnHold.size();
4397            if (NP > 0) {
4398                ArrayList<ProcessRecord> procs =
4399                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4400                for (int ip=0; ip<NP; ip++) {
4401                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4402                            + procs.get(ip));
4403                    startProcessLocked(procs.get(ip), "on-hold", null);
4404                }
4405            }
4406
4407            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4408                // Start looking for apps that are abusing wake locks.
4409                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4410                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4411                // Tell anyone interested that we are done booting!
4412                SystemProperties.set("sys.boot_completed", "1");
4413                SystemProperties.set("dev.bootcomplete", "1");
4414                for (int i=0; i<mStartedUsers.size(); i++) {
4415                    UserStartedState uss = mStartedUsers.valueAt(i);
4416                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4417                        uss.mState = UserStartedState.STATE_RUNNING;
4418                        final int userId = mStartedUsers.keyAt(i);
4419                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4420                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4421                        broadcastIntentLocked(null, null, intent,
4422                                null, null, 0, null, null,
4423                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4424                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4425                    }
4426                }
4427            }
4428        }
4429    }
4430
4431    final void ensureBootCompleted() {
4432        boolean booting;
4433        boolean enableScreen;
4434        synchronized (this) {
4435            booting = mBooting;
4436            mBooting = false;
4437            enableScreen = !mBooted;
4438            mBooted = true;
4439        }
4440
4441        if (booting) {
4442            finishBooting();
4443        }
4444
4445        if (enableScreen) {
4446            enableScreenAfterBoot();
4447        }
4448    }
4449
4450    public final void activityResumed(IBinder token) {
4451        final long origId = Binder.clearCallingIdentity();
4452        mMainStack.activityResumed(token);
4453        Binder.restoreCallingIdentity(origId);
4454    }
4455
4456    public final void activityPaused(IBinder token) {
4457        final long origId = Binder.clearCallingIdentity();
4458        mMainStack.activityPaused(token, false);
4459        Binder.restoreCallingIdentity(origId);
4460    }
4461
4462    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4463            CharSequence description) {
4464        if (localLOGV) Slog.v(
4465            TAG, "Activity stopped: token=" + token);
4466
4467        // Refuse possible leaked file descriptors
4468        if (icicle != null && icicle.hasFileDescriptors()) {
4469            throw new IllegalArgumentException("File descriptors passed in Bundle");
4470        }
4471
4472        ActivityRecord r = null;
4473
4474        final long origId = Binder.clearCallingIdentity();
4475
4476        synchronized (this) {
4477            r = mMainStack.isInStackLocked(token);
4478            if (r != null) {
4479                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4480            }
4481        }
4482
4483        if (r != null) {
4484            sendPendingThumbnail(r, null, null, null, false);
4485        }
4486
4487        trimApplications();
4488
4489        Binder.restoreCallingIdentity(origId);
4490    }
4491
4492    public final void activityDestroyed(IBinder token) {
4493        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4494        mMainStack.activityDestroyed(token);
4495    }
4496
4497    public String getCallingPackage(IBinder token) {
4498        synchronized (this) {
4499            ActivityRecord r = getCallingRecordLocked(token);
4500            return r != null && r.app != null ? r.info.packageName : null;
4501        }
4502    }
4503
4504    public ComponentName getCallingActivity(IBinder token) {
4505        synchronized (this) {
4506            ActivityRecord r = getCallingRecordLocked(token);
4507            return r != null ? r.intent.getComponent() : null;
4508        }
4509    }
4510
4511    private ActivityRecord getCallingRecordLocked(IBinder token) {
4512        ActivityRecord r = mMainStack.isInStackLocked(token);
4513        if (r == null) {
4514            return null;
4515        }
4516        return r.resultTo;
4517    }
4518
4519    public ComponentName getActivityClassForToken(IBinder token) {
4520        synchronized(this) {
4521            ActivityRecord r = mMainStack.isInStackLocked(token);
4522            if (r == null) {
4523                return null;
4524            }
4525            return r.intent.getComponent();
4526        }
4527    }
4528
4529    public String getPackageForToken(IBinder token) {
4530        synchronized(this) {
4531            ActivityRecord r = mMainStack.isInStackLocked(token);
4532            if (r == null) {
4533                return null;
4534            }
4535            return r.packageName;
4536        }
4537    }
4538
4539    public IIntentSender getIntentSender(int type,
4540            String packageName, IBinder token, String resultWho,
4541            int requestCode, Intent[] intents, String[] resolvedTypes,
4542            int flags, Bundle options, int userId) {
4543        enforceNotIsolatedCaller("getIntentSender");
4544        // Refuse possible leaked file descriptors
4545        if (intents != null) {
4546            if (intents.length < 1) {
4547                throw new IllegalArgumentException("Intents array length must be >= 1");
4548            }
4549            for (int i=0; i<intents.length; i++) {
4550                Intent intent = intents[i];
4551                if (intent != null) {
4552                    if (intent.hasFileDescriptors()) {
4553                        throw new IllegalArgumentException("File descriptors passed in Intent");
4554                    }
4555                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4556                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4557                        throw new IllegalArgumentException(
4558                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4559                    }
4560                    intents[i] = new Intent(intent);
4561                }
4562            }
4563            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4564                throw new IllegalArgumentException(
4565                        "Intent array length does not match resolvedTypes length");
4566            }
4567        }
4568        if (options != null) {
4569            if (options.hasFileDescriptors()) {
4570                throw new IllegalArgumentException("File descriptors passed in options");
4571            }
4572        }
4573
4574        synchronized(this) {
4575            int callingUid = Binder.getCallingUid();
4576            int origUserId = userId;
4577            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4578                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4579                    "getIntentSender", null);
4580            if (origUserId == UserHandle.USER_CURRENT) {
4581                // We don't want to evaluate this until the pending intent is
4582                // actually executed.  However, we do want to always do the
4583                // security checking for it above.
4584                userId = UserHandle.USER_CURRENT;
4585            }
4586            try {
4587                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4588                    int uid = AppGlobals.getPackageManager()
4589                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4590                    if (!UserHandle.isSameApp(callingUid, uid)) {
4591                        String msg = "Permission Denial: getIntentSender() from pid="
4592                            + Binder.getCallingPid()
4593                            + ", uid=" + Binder.getCallingUid()
4594                            + ", (need uid=" + uid + ")"
4595                            + " is not allowed to send as package " + packageName;
4596                        Slog.w(TAG, msg);
4597                        throw new SecurityException(msg);
4598                    }
4599                }
4600
4601                return getIntentSenderLocked(type, packageName, callingUid, userId,
4602                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4603
4604            } catch (RemoteException e) {
4605                throw new SecurityException(e);
4606            }
4607        }
4608    }
4609
4610    IIntentSender getIntentSenderLocked(int type, String packageName,
4611            int callingUid, int userId, IBinder token, String resultWho,
4612            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4613            Bundle options) {
4614        if (DEBUG_MU)
4615            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4616        ActivityRecord activity = null;
4617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4618            activity = mMainStack.isInStackLocked(token);
4619            if (activity == null) {
4620                return null;
4621            }
4622            if (activity.finishing) {
4623                return null;
4624            }
4625        }
4626
4627        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4628        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4629        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4630        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4631                |PendingIntent.FLAG_UPDATE_CURRENT);
4632
4633        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4634                type, packageName, activity, resultWho,
4635                requestCode, intents, resolvedTypes, flags, options, userId);
4636        WeakReference<PendingIntentRecord> ref;
4637        ref = mIntentSenderRecords.get(key);
4638        PendingIntentRecord rec = ref != null ? ref.get() : null;
4639        if (rec != null) {
4640            if (!cancelCurrent) {
4641                if (updateCurrent) {
4642                    if (rec.key.requestIntent != null) {
4643                        rec.key.requestIntent.replaceExtras(intents != null ?
4644                                intents[intents.length - 1] : null);
4645                    }
4646                    if (intents != null) {
4647                        intents[intents.length-1] = rec.key.requestIntent;
4648                        rec.key.allIntents = intents;
4649                        rec.key.allResolvedTypes = resolvedTypes;
4650                    } else {
4651                        rec.key.allIntents = null;
4652                        rec.key.allResolvedTypes = null;
4653                    }
4654                }
4655                return rec;
4656            }
4657            rec.canceled = true;
4658            mIntentSenderRecords.remove(key);
4659        }
4660        if (noCreate) {
4661            return rec;
4662        }
4663        rec = new PendingIntentRecord(this, key, callingUid);
4664        mIntentSenderRecords.put(key, rec.ref);
4665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4666            if (activity.pendingResults == null) {
4667                activity.pendingResults
4668                        = new HashSet<WeakReference<PendingIntentRecord>>();
4669            }
4670            activity.pendingResults.add(rec.ref);
4671        }
4672        return rec;
4673    }
4674
4675    public void cancelIntentSender(IIntentSender sender) {
4676        if (!(sender instanceof PendingIntentRecord)) {
4677            return;
4678        }
4679        synchronized(this) {
4680            PendingIntentRecord rec = (PendingIntentRecord)sender;
4681            try {
4682                int uid = AppGlobals.getPackageManager()
4683                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4684                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4685                    String msg = "Permission Denial: cancelIntentSender() from pid="
4686                        + Binder.getCallingPid()
4687                        + ", uid=" + Binder.getCallingUid()
4688                        + " is not allowed to cancel packges "
4689                        + rec.key.packageName;
4690                    Slog.w(TAG, msg);
4691                    throw new SecurityException(msg);
4692                }
4693            } catch (RemoteException e) {
4694                throw new SecurityException(e);
4695            }
4696            cancelIntentSenderLocked(rec, true);
4697        }
4698    }
4699
4700    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4701        rec.canceled = true;
4702        mIntentSenderRecords.remove(rec.key);
4703        if (cleanActivity && rec.key.activity != null) {
4704            rec.key.activity.pendingResults.remove(rec.ref);
4705        }
4706    }
4707
4708    public String getPackageForIntentSender(IIntentSender pendingResult) {
4709        if (!(pendingResult instanceof PendingIntentRecord)) {
4710            return null;
4711        }
4712        try {
4713            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4714            return res.key.packageName;
4715        } catch (ClassCastException e) {
4716        }
4717        return null;
4718    }
4719
4720    public int getUidForIntentSender(IIntentSender sender) {
4721        if (sender instanceof PendingIntentRecord) {
4722            try {
4723                PendingIntentRecord res = (PendingIntentRecord)sender;
4724                return res.uid;
4725            } catch (ClassCastException e) {
4726            }
4727        }
4728        return -1;
4729    }
4730
4731    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4732        if (!(pendingResult instanceof PendingIntentRecord)) {
4733            return false;
4734        }
4735        try {
4736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4737            if (res.key.allIntents == null) {
4738                return false;
4739            }
4740            for (int i=0; i<res.key.allIntents.length; i++) {
4741                Intent intent = res.key.allIntents[i];
4742                if (intent.getPackage() != null && intent.getComponent() != null) {
4743                    return false;
4744                }
4745            }
4746            return true;
4747        } catch (ClassCastException e) {
4748        }
4749        return false;
4750    }
4751
4752    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4753        if (!(pendingResult instanceof PendingIntentRecord)) {
4754            return false;
4755        }
4756        try {
4757            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4758            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4759                return true;
4760            }
4761            return false;
4762        } catch (ClassCastException e) {
4763        }
4764        return false;
4765    }
4766
4767    public void setProcessLimit(int max) {
4768        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4769                "setProcessLimit()");
4770        synchronized (this) {
4771            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4772            mProcessLimitOverride = max;
4773        }
4774        trimApplications();
4775    }
4776
4777    public int getProcessLimit() {
4778        synchronized (this) {
4779            return mProcessLimitOverride;
4780        }
4781    }
4782
4783    void foregroundTokenDied(ForegroundToken token) {
4784        synchronized (ActivityManagerService.this) {
4785            synchronized (mPidsSelfLocked) {
4786                ForegroundToken cur
4787                    = mForegroundProcesses.get(token.pid);
4788                if (cur != token) {
4789                    return;
4790                }
4791                mForegroundProcesses.remove(token.pid);
4792                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4793                if (pr == null) {
4794                    return;
4795                }
4796                pr.forcingToForeground = null;
4797                pr.foregroundServices = false;
4798            }
4799            updateOomAdjLocked();
4800        }
4801    }
4802
4803    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4804        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4805                "setProcessForeground()");
4806        synchronized(this) {
4807            boolean changed = false;
4808
4809            synchronized (mPidsSelfLocked) {
4810                ProcessRecord pr = mPidsSelfLocked.get(pid);
4811                if (pr == null && isForeground) {
4812                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4813                    return;
4814                }
4815                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4816                if (oldToken != null) {
4817                    oldToken.token.unlinkToDeath(oldToken, 0);
4818                    mForegroundProcesses.remove(pid);
4819                    if (pr != null) {
4820                        pr.forcingToForeground = null;
4821                    }
4822                    changed = true;
4823                }
4824                if (isForeground && token != null) {
4825                    ForegroundToken newToken = new ForegroundToken() {
4826                        public void binderDied() {
4827                            foregroundTokenDied(this);
4828                        }
4829                    };
4830                    newToken.pid = pid;
4831                    newToken.token = token;
4832                    try {
4833                        token.linkToDeath(newToken, 0);
4834                        mForegroundProcesses.put(pid, newToken);
4835                        pr.forcingToForeground = token;
4836                        changed = true;
4837                    } catch (RemoteException e) {
4838                        // If the process died while doing this, we will later
4839                        // do the cleanup with the process death link.
4840                    }
4841                }
4842            }
4843
4844            if (changed) {
4845                updateOomAdjLocked();
4846            }
4847        }
4848    }
4849
4850    // =========================================================
4851    // PERMISSIONS
4852    // =========================================================
4853
4854    static class PermissionController extends IPermissionController.Stub {
4855        ActivityManagerService mActivityManagerService;
4856        PermissionController(ActivityManagerService activityManagerService) {
4857            mActivityManagerService = activityManagerService;
4858        }
4859
4860        public boolean checkPermission(String permission, int pid, int uid) {
4861            return mActivityManagerService.checkPermission(permission, pid,
4862                    uid) == PackageManager.PERMISSION_GRANTED;
4863        }
4864    }
4865
4866    /**
4867     * This can be called with or without the global lock held.
4868     */
4869    int checkComponentPermission(String permission, int pid, int uid,
4870            int owningUid, boolean exported) {
4871        // We might be performing an operation on behalf of an indirect binder
4872        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4873        // client identity accordingly before proceeding.
4874        Identity tlsIdentity = sCallerIdentity.get();
4875        if (tlsIdentity != null) {
4876            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4877                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4878            uid = tlsIdentity.uid;
4879            pid = tlsIdentity.pid;
4880        }
4881
4882        if (pid == MY_PID) {
4883            return PackageManager.PERMISSION_GRANTED;
4884        }
4885
4886        return ActivityManager.checkComponentPermission(permission, uid,
4887                owningUid, exported);
4888    }
4889
4890    /**
4891     * As the only public entry point for permissions checking, this method
4892     * can enforce the semantic that requesting a check on a null global
4893     * permission is automatically denied.  (Internally a null permission
4894     * string is used when calling {@link #checkComponentPermission} in cases
4895     * when only uid-based security is needed.)
4896     *
4897     * This can be called with or without the global lock held.
4898     */
4899    public int checkPermission(String permission, int pid, int uid) {
4900        if (permission == null) {
4901            return PackageManager.PERMISSION_DENIED;
4902        }
4903        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4904    }
4905
4906    /**
4907     * Binder IPC calls go through the public entry point.
4908     * This can be called with or without the global lock held.
4909     */
4910    int checkCallingPermission(String permission) {
4911        return checkPermission(permission,
4912                Binder.getCallingPid(),
4913                UserHandle.getAppId(Binder.getCallingUid()));
4914    }
4915
4916    /**
4917     * This can be called with or without the global lock held.
4918     */
4919    void enforceCallingPermission(String permission, String func) {
4920        if (checkCallingPermission(permission)
4921                == PackageManager.PERMISSION_GRANTED) {
4922            return;
4923        }
4924
4925        String msg = "Permission Denial: " + func + " from pid="
4926                + Binder.getCallingPid()
4927                + ", uid=" + Binder.getCallingUid()
4928                + " requires " + permission;
4929        Slog.w(TAG, msg);
4930        throw new SecurityException(msg);
4931    }
4932
4933    /**
4934     * Determine if UID is holding permissions required to access {@link Uri} in
4935     * the given {@link ProviderInfo}. Final permission checking is always done
4936     * in {@link ContentProvider}.
4937     */
4938    private final boolean checkHoldingPermissionsLocked(
4939            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4940        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4941                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4942
4943        if (pi.applicationInfo.uid == uid) {
4944            return true;
4945        } else if (!pi.exported) {
4946            return false;
4947        }
4948
4949        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4950        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4951        try {
4952            // check if target holds top-level <provider> permissions
4953            if (!readMet && pi.readPermission != null
4954                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4955                readMet = true;
4956            }
4957            if (!writeMet && pi.writePermission != null
4958                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4959                writeMet = true;
4960            }
4961
4962            // track if unprotected read/write is allowed; any denied
4963            // <path-permission> below removes this ability
4964            boolean allowDefaultRead = pi.readPermission == null;
4965            boolean allowDefaultWrite = pi.writePermission == null;
4966
4967            // check if target holds any <path-permission> that match uri
4968            final PathPermission[] pps = pi.pathPermissions;
4969            if (pps != null) {
4970                final String path = uri.getPath();
4971                int i = pps.length;
4972                while (i > 0 && (!readMet || !writeMet)) {
4973                    i--;
4974                    PathPermission pp = pps[i];
4975                    if (pp.match(path)) {
4976                        if (!readMet) {
4977                            final String pprperm = pp.getReadPermission();
4978                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4979                                    + pprperm + " for " + pp.getPath()
4980                                    + ": match=" + pp.match(path)
4981                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4982                            if (pprperm != null) {
4983                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4984                                    readMet = true;
4985                                } else {
4986                                    allowDefaultRead = false;
4987                                }
4988                            }
4989                        }
4990                        if (!writeMet) {
4991                            final String ppwperm = pp.getWritePermission();
4992                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4993                                    + ppwperm + " for " + pp.getPath()
4994                                    + ": match=" + pp.match(path)
4995                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4996                            if (ppwperm != null) {
4997                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4998                                    writeMet = true;
4999                                } else {
5000                                    allowDefaultWrite = false;
5001                                }
5002                            }
5003                        }
5004                    }
5005                }
5006            }
5007
5008            // grant unprotected <provider> read/write, if not blocked by
5009            // <path-permission> above
5010            if (allowDefaultRead) readMet = true;
5011            if (allowDefaultWrite) writeMet = true;
5012
5013        } catch (RemoteException e) {
5014            return false;
5015        }
5016
5017        return readMet && writeMet;
5018    }
5019
5020    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5021            int modeFlags) {
5022        // Root gets to do everything.
5023        if (uid == 0) {
5024            return true;
5025        }
5026        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5027        if (perms == null) return false;
5028        UriPermission perm = perms.get(uri);
5029        if (perm == null) return false;
5030        return (modeFlags&perm.modeFlags) == modeFlags;
5031    }
5032
5033    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5034        enforceNotIsolatedCaller("checkUriPermission");
5035
5036        // Another redirected-binder-call permissions check as in
5037        // {@link checkComponentPermission}.
5038        Identity tlsIdentity = sCallerIdentity.get();
5039        if (tlsIdentity != null) {
5040            uid = tlsIdentity.uid;
5041            pid = tlsIdentity.pid;
5042        }
5043
5044        // Our own process gets to do everything.
5045        if (pid == MY_PID) {
5046            return PackageManager.PERMISSION_GRANTED;
5047        }
5048        synchronized(this) {
5049            return checkUriPermissionLocked(uri, uid, modeFlags)
5050                    ? PackageManager.PERMISSION_GRANTED
5051                    : PackageManager.PERMISSION_DENIED;
5052        }
5053    }
5054
5055    /**
5056     * Check if the targetPkg can be granted permission to access uri by
5057     * the callingUid using the given modeFlags.  Throws a security exception
5058     * if callingUid is not allowed to do this.  Returns the uid of the target
5059     * if the URI permission grant should be performed; returns -1 if it is not
5060     * needed (for example targetPkg already has permission to access the URI).
5061     * If you already know the uid of the target, you can supply it in
5062     * lastTargetUid else set that to -1.
5063     */
5064    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5065            Uri uri, int modeFlags, int lastTargetUid) {
5066        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5067                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5068        if (modeFlags == 0) {
5069            return -1;
5070        }
5071
5072        if (targetPkg != null) {
5073            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5074                    "Checking grant " + targetPkg + " permission to " + uri);
5075        }
5076
5077        final IPackageManager pm = AppGlobals.getPackageManager();
5078
5079        // If this is not a content: uri, we can't do anything with it.
5080        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5082                    "Can't grant URI permission for non-content URI: " + uri);
5083            return -1;
5084        }
5085
5086        String name = uri.getAuthority();
5087        ProviderInfo pi = null;
5088        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5089                UserHandle.getUserId(callingUid));
5090        if (cpr != null) {
5091            pi = cpr.info;
5092        } else {
5093            try {
5094                pi = pm.resolveContentProvider(name,
5095                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5096                        UserHandle.getUserId(callingUid));
5097            } catch (RemoteException ex) {
5098            }
5099        }
5100        if (pi == null) {
5101            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5102            return -1;
5103        }
5104
5105        int targetUid = lastTargetUid;
5106        if (targetUid < 0 && targetPkg != null) {
5107            try {
5108                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5109                if (targetUid < 0) {
5110                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5111                            "Can't grant URI permission no uid for: " + targetPkg);
5112                    return -1;
5113                }
5114            } catch (RemoteException ex) {
5115                return -1;
5116            }
5117        }
5118
5119        if (targetUid >= 0) {
5120            // First...  does the target actually need this permission?
5121            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5122                // No need to grant the target this permission.
5123                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5124                        "Target " + targetPkg + " already has full permission to " + uri);
5125                return -1;
5126            }
5127        } else {
5128            // First...  there is no target package, so can anyone access it?
5129            boolean allowed = pi.exported;
5130            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5131                if (pi.readPermission != null) {
5132                    allowed = false;
5133                }
5134            }
5135            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5136                if (pi.writePermission != null) {
5137                    allowed = false;
5138                }
5139            }
5140            if (allowed) {
5141                return -1;
5142            }
5143        }
5144
5145        // Second...  is the provider allowing granting of URI permissions?
5146        if (!pi.grantUriPermissions) {
5147            throw new SecurityException("Provider " + pi.packageName
5148                    + "/" + pi.name
5149                    + " does not allow granting of Uri permissions (uri "
5150                    + uri + ")");
5151        }
5152        if (pi.uriPermissionPatterns != null) {
5153            final int N = pi.uriPermissionPatterns.length;
5154            boolean allowed = false;
5155            for (int i=0; i<N; i++) {
5156                if (pi.uriPermissionPatterns[i] != null
5157                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5158                    allowed = true;
5159                    break;
5160                }
5161            }
5162            if (!allowed) {
5163                throw new SecurityException("Provider " + pi.packageName
5164                        + "/" + pi.name
5165                        + " does not allow granting of permission to path of Uri "
5166                        + uri);
5167            }
5168        }
5169
5170        // Third...  does the caller itself have permission to access
5171        // this uri?
5172        if (callingUid != Process.myUid()) {
5173            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5174                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5175                    throw new SecurityException("Uid " + callingUid
5176                            + " does not have permission to uri " + uri);
5177                }
5178            }
5179        }
5180
5181        return targetUid;
5182    }
5183
5184    public int checkGrantUriPermission(int callingUid, String targetPkg,
5185            Uri uri, int modeFlags) {
5186        enforceNotIsolatedCaller("checkGrantUriPermission");
5187        synchronized(this) {
5188            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5189        }
5190    }
5191
5192    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5193            Uri uri, int modeFlags, UriPermissionOwner owner) {
5194        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5195                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5196        if (modeFlags == 0) {
5197            return;
5198        }
5199
5200        // So here we are: the caller has the assumed permission
5201        // to the uri, and the target doesn't.  Let's now give this to
5202        // the target.
5203
5204        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5205                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5206
5207        HashMap<Uri, UriPermission> targetUris
5208                = mGrantedUriPermissions.get(targetUid);
5209        if (targetUris == null) {
5210            targetUris = new HashMap<Uri, UriPermission>();
5211            mGrantedUriPermissions.put(targetUid, targetUris);
5212        }
5213
5214        UriPermission perm = targetUris.get(uri);
5215        if (perm == null) {
5216            perm = new UriPermission(targetUid, uri);
5217            targetUris.put(uri, perm);
5218        }
5219
5220        perm.modeFlags |= modeFlags;
5221        if (owner == null) {
5222            perm.globalModeFlags |= modeFlags;
5223        } else {
5224            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5225                 perm.readOwners.add(owner);
5226                 owner.addReadPermission(perm);
5227            }
5228            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5229                 perm.writeOwners.add(owner);
5230                 owner.addWritePermission(perm);
5231            }
5232        }
5233    }
5234
5235    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5236            int modeFlags, UriPermissionOwner owner) {
5237        if (targetPkg == null) {
5238            throw new NullPointerException("targetPkg");
5239        }
5240
5241        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5242        if (targetUid < 0) {
5243            return;
5244        }
5245
5246        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5247    }
5248
5249    static class NeededUriGrants extends ArrayList<Uri> {
5250        final String targetPkg;
5251        final int targetUid;
5252        final int flags;
5253
5254        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5255            targetPkg = _targetPkg;
5256            targetUid = _targetUid;
5257            flags = _flags;
5258        }
5259    }
5260
5261    /**
5262     * Like checkGrantUriPermissionLocked, but takes an Intent.
5263     */
5264    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5265            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5266        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5267                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5268                + " clip=" + (intent != null ? intent.getClipData() : null)
5269                + " from " + intent + "; flags=0x"
5270                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5271
5272        if (targetPkg == null) {
5273            throw new NullPointerException("targetPkg");
5274        }
5275
5276        if (intent == null) {
5277            return null;
5278        }
5279        Uri data = intent.getData();
5280        ClipData clip = intent.getClipData();
5281        if (data == null && clip == null) {
5282            return null;
5283        }
5284        if (data != null) {
5285            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5286                mode, needed != null ? needed.targetUid : -1);
5287            if (target > 0) {
5288                if (needed == null) {
5289                    needed = new NeededUriGrants(targetPkg, target, mode);
5290                }
5291                needed.add(data);
5292            }
5293        }
5294        if (clip != null) {
5295            for (int i=0; i<clip.getItemCount(); i++) {
5296                Uri uri = clip.getItemAt(i).getUri();
5297                if (uri != null) {
5298                    int target = -1;
5299                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5300                            mode, needed != null ? needed.targetUid : -1);
5301                    if (target > 0) {
5302                        if (needed == null) {
5303                            needed = new NeededUriGrants(targetPkg, target, mode);
5304                        }
5305                        needed.add(uri);
5306                    }
5307                } else {
5308                    Intent clipIntent = clip.getItemAt(i).getIntent();
5309                    if (clipIntent != null) {
5310                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5311                                callingUid, targetPkg, clipIntent, mode, needed);
5312                        if (newNeeded != null) {
5313                            needed = newNeeded;
5314                        }
5315                    }
5316                }
5317            }
5318        }
5319
5320        return needed;
5321    }
5322
5323    /**
5324     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5325     */
5326    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5327            UriPermissionOwner owner) {
5328        if (needed != null) {
5329            for (int i=0; i<needed.size(); i++) {
5330                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5331                        needed.get(i), needed.flags, owner);
5332            }
5333        }
5334    }
5335
5336    void grantUriPermissionFromIntentLocked(int callingUid,
5337            String targetPkg, Intent intent, UriPermissionOwner owner) {
5338        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5339                intent, intent != null ? intent.getFlags() : 0, null);
5340        if (needed == null) {
5341            return;
5342        }
5343
5344        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5345    }
5346
5347    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5348            Uri uri, int modeFlags) {
5349        enforceNotIsolatedCaller("grantUriPermission");
5350        synchronized(this) {
5351            final ProcessRecord r = getRecordForAppLocked(caller);
5352            if (r == null) {
5353                throw new SecurityException("Unable to find app for caller "
5354                        + caller
5355                        + " when granting permission to uri " + uri);
5356            }
5357            if (targetPkg == null) {
5358                throw new IllegalArgumentException("null target");
5359            }
5360            if (uri == null) {
5361                throw new IllegalArgumentException("null uri");
5362            }
5363
5364            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5365                    null);
5366        }
5367    }
5368
5369    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5370        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5371                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5372            HashMap<Uri, UriPermission> perms
5373                    = mGrantedUriPermissions.get(perm.uid);
5374            if (perms != null) {
5375                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5376                        "Removing " + perm.uid + " permission to " + perm.uri);
5377                perms.remove(perm.uri);
5378                if (perms.size() == 0) {
5379                    mGrantedUriPermissions.remove(perm.uid);
5380                }
5381            }
5382        }
5383    }
5384
5385    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5386            int modeFlags) {
5387        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5388                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5389        if (modeFlags == 0) {
5390            return;
5391        }
5392
5393        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5394                "Revoking all granted permissions to " + uri);
5395
5396        final IPackageManager pm = AppGlobals.getPackageManager();
5397
5398        final String authority = uri.getAuthority();
5399        ProviderInfo pi = null;
5400        int userId = UserHandle.getUserId(callingUid);
5401        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5402        if (cpr != null) {
5403            pi = cpr.info;
5404        } else {
5405            try {
5406                pi = pm.resolveContentProvider(authority,
5407                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5408            } catch (RemoteException ex) {
5409            }
5410        }
5411        if (pi == null) {
5412            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5413            return;
5414        }
5415
5416        // Does the caller have this permission on the URI?
5417        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5418            // Right now, if you are not the original owner of the permission,
5419            // you are not allowed to revoke it.
5420            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5421                throw new SecurityException("Uid " + callingUid
5422                        + " does not have permission to uri " + uri);
5423            //}
5424        }
5425
5426        // Go through all of the permissions and remove any that match.
5427        final List<String> SEGMENTS = uri.getPathSegments();
5428        if (SEGMENTS != null) {
5429            final int NS = SEGMENTS.size();
5430            int N = mGrantedUriPermissions.size();
5431            for (int i=0; i<N; i++) {
5432                HashMap<Uri, UriPermission> perms
5433                        = mGrantedUriPermissions.valueAt(i);
5434                Iterator<UriPermission> it = perms.values().iterator();
5435            toploop:
5436                while (it.hasNext()) {
5437                    UriPermission perm = it.next();
5438                    Uri targetUri = perm.uri;
5439                    if (!authority.equals(targetUri.getAuthority())) {
5440                        continue;
5441                    }
5442                    List<String> targetSegments = targetUri.getPathSegments();
5443                    if (targetSegments == null) {
5444                        continue;
5445                    }
5446                    if (targetSegments.size() < NS) {
5447                        continue;
5448                    }
5449                    for (int j=0; j<NS; j++) {
5450                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5451                            continue toploop;
5452                        }
5453                    }
5454                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5455                            "Revoking " + perm.uid + " permission to " + perm.uri);
5456                    perm.clearModes(modeFlags);
5457                    if (perm.modeFlags == 0) {
5458                        it.remove();
5459                    }
5460                }
5461                if (perms.size() == 0) {
5462                    mGrantedUriPermissions.remove(
5463                            mGrantedUriPermissions.keyAt(i));
5464                    N--;
5465                    i--;
5466                }
5467            }
5468        }
5469    }
5470
5471    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5472            int modeFlags) {
5473        enforceNotIsolatedCaller("revokeUriPermission");
5474        synchronized(this) {
5475            final ProcessRecord r = getRecordForAppLocked(caller);
5476            if (r == null) {
5477                throw new SecurityException("Unable to find app for caller "
5478                        + caller
5479                        + " when revoking permission to uri " + uri);
5480            }
5481            if (uri == null) {
5482                Slog.w(TAG, "revokeUriPermission: null uri");
5483                return;
5484            }
5485
5486            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5487                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5488            if (modeFlags == 0) {
5489                return;
5490            }
5491
5492            final IPackageManager pm = AppGlobals.getPackageManager();
5493
5494            final String authority = uri.getAuthority();
5495            ProviderInfo pi = null;
5496            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5497            if (cpr != null) {
5498                pi = cpr.info;
5499            } else {
5500                try {
5501                    pi = pm.resolveContentProvider(authority,
5502                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5503                } catch (RemoteException ex) {
5504                }
5505            }
5506            if (pi == null) {
5507                Slog.w(TAG, "No content provider found for permission revoke: "
5508                        + uri.toSafeString());
5509                return;
5510            }
5511
5512            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5513        }
5514    }
5515
5516    @Override
5517    public IBinder newUriPermissionOwner(String name) {
5518        enforceNotIsolatedCaller("newUriPermissionOwner");
5519        synchronized(this) {
5520            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5521            return owner.getExternalTokenLocked();
5522        }
5523    }
5524
5525    @Override
5526    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5527            Uri uri, int modeFlags) {
5528        synchronized(this) {
5529            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5530            if (owner == null) {
5531                throw new IllegalArgumentException("Unknown owner: " + token);
5532            }
5533            if (fromUid != Binder.getCallingUid()) {
5534                if (Binder.getCallingUid() != Process.myUid()) {
5535                    // Only system code can grant URI permissions on behalf
5536                    // of other users.
5537                    throw new SecurityException("nice try");
5538                }
5539            }
5540            if (targetPkg == null) {
5541                throw new IllegalArgumentException("null target");
5542            }
5543            if (uri == null) {
5544                throw new IllegalArgumentException("null uri");
5545            }
5546
5547            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5548        }
5549    }
5550
5551    @Override
5552    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5553        synchronized(this) {
5554            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5555            if (owner == null) {
5556                throw new IllegalArgumentException("Unknown owner: " + token);
5557            }
5558
5559            if (uri == null) {
5560                owner.removeUriPermissionsLocked(mode);
5561            } else {
5562                owner.removeUriPermissionLocked(uri, mode);
5563            }
5564        }
5565    }
5566
5567    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5568        synchronized (this) {
5569            ProcessRecord app =
5570                who != null ? getRecordForAppLocked(who) : null;
5571            if (app == null) return;
5572
5573            Message msg = Message.obtain();
5574            msg.what = WAIT_FOR_DEBUGGER_MSG;
5575            msg.obj = app;
5576            msg.arg1 = waiting ? 1 : 0;
5577            mHandler.sendMessage(msg);
5578        }
5579    }
5580
5581    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5582        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5583        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5584        outInfo.availMem = Process.getFreeMemory();
5585        outInfo.totalMem = Process.getTotalMemory();
5586        outInfo.threshold = homeAppMem;
5587        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5588        outInfo.hiddenAppThreshold = hiddenAppMem;
5589        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5590                ProcessList.SERVICE_ADJ);
5591        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5592                ProcessList.VISIBLE_APP_ADJ);
5593        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5594                ProcessList.FOREGROUND_APP_ADJ);
5595    }
5596
5597    // =========================================================
5598    // TASK MANAGEMENT
5599    // =========================================================
5600
5601    public List getTasks(int maxNum, int flags,
5602                         IThumbnailReceiver receiver) {
5603        ArrayList list = new ArrayList();
5604
5605        PendingThumbnailsRecord pending = null;
5606        IApplicationThread topThumbnail = null;
5607        ActivityRecord topRecord = null;
5608
5609        synchronized(this) {
5610            if (localLOGV) Slog.v(
5611                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5612                + ", receiver=" + receiver);
5613
5614            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5615                    != PackageManager.PERMISSION_GRANTED) {
5616                if (receiver != null) {
5617                    // If the caller wants to wait for pending thumbnails,
5618                    // it ain't gonna get them.
5619                    try {
5620                        receiver.finished();
5621                    } catch (RemoteException ex) {
5622                    }
5623                }
5624                String msg = "Permission Denial: getTasks() from pid="
5625                        + Binder.getCallingPid()
5626                        + ", uid=" + Binder.getCallingUid()
5627                        + " requires " + android.Manifest.permission.GET_TASKS;
5628                Slog.w(TAG, msg);
5629                throw new SecurityException(msg);
5630            }
5631
5632            int pos = mMainStack.mHistory.size()-1;
5633            ActivityRecord next =
5634                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5635            ActivityRecord top = null;
5636            TaskRecord curTask = null;
5637            int numActivities = 0;
5638            int numRunning = 0;
5639            while (pos >= 0 && maxNum > 0) {
5640                final ActivityRecord r = next;
5641                pos--;
5642                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5643
5644                // Initialize state for next task if needed.
5645                if (top == null ||
5646                        (top.state == ActivityState.INITIALIZING
5647                            && top.task == r.task)) {
5648                    top = r;
5649                    curTask = r.task;
5650                    numActivities = numRunning = 0;
5651                }
5652
5653                // Add 'r' into the current task.
5654                numActivities++;
5655                if (r.app != null && r.app.thread != null) {
5656                    numRunning++;
5657                }
5658
5659                if (localLOGV) Slog.v(
5660                    TAG, r.intent.getComponent().flattenToShortString()
5661                    + ": task=" + r.task);
5662
5663                // If the next one is a different task, generate a new
5664                // TaskInfo entry for what we have.
5665                if (next == null || next.task != curTask) {
5666                    ActivityManager.RunningTaskInfo ci
5667                            = new ActivityManager.RunningTaskInfo();
5668                    ci.id = curTask.taskId;
5669                    ci.baseActivity = r.intent.getComponent();
5670                    ci.topActivity = top.intent.getComponent();
5671                    if (top.thumbHolder != null) {
5672                        ci.description = top.thumbHolder.lastDescription;
5673                    }
5674                    ci.numActivities = numActivities;
5675                    ci.numRunning = numRunning;
5676                    //System.out.println(
5677                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5678                    if (ci.thumbnail == null && receiver != null) {
5679                        if (localLOGV) Slog.v(
5680                            TAG, "State=" + top.state + "Idle=" + top.idle
5681                            + " app=" + top.app
5682                            + " thr=" + (top.app != null ? top.app.thread : null));
5683                        if (top.state == ActivityState.RESUMED
5684                                || top.state == ActivityState.PAUSING) {
5685                            if (top.idle && top.app != null
5686                                && top.app.thread != null) {
5687                                topRecord = top;
5688                                topThumbnail = top.app.thread;
5689                            } else {
5690                                top.thumbnailNeeded = true;
5691                            }
5692                        }
5693                        if (pending == null) {
5694                            pending = new PendingThumbnailsRecord(receiver);
5695                        }
5696                        pending.pendingRecords.add(top);
5697                    }
5698                    list.add(ci);
5699                    maxNum--;
5700                    top = null;
5701                }
5702            }
5703
5704            if (pending != null) {
5705                mPendingThumbnails.add(pending);
5706            }
5707        }
5708
5709        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5710
5711        if (topThumbnail != null) {
5712            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5713            try {
5714                topThumbnail.requestThumbnail(topRecord.appToken);
5715            } catch (Exception e) {
5716                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5717                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5718            }
5719        }
5720
5721        if (pending == null && receiver != null) {
5722            // In this case all thumbnails were available and the client
5723            // is being asked to be told when the remaining ones come in...
5724            // which is unusually, since the top-most currently running
5725            // activity should never have a canned thumbnail!  Oh well.
5726            try {
5727                receiver.finished();
5728            } catch (RemoteException ex) {
5729            }
5730        }
5731
5732        return list;
5733    }
5734
5735    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5736            int flags, int userId) {
5737        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5738                false, true, "getRecentTasks", null);
5739
5740        synchronized (this) {
5741            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5742                    "getRecentTasks()");
5743            final boolean detailed = checkCallingPermission(
5744                    android.Manifest.permission.GET_DETAILED_TASKS)
5745                    == PackageManager.PERMISSION_GRANTED;
5746
5747            IPackageManager pm = AppGlobals.getPackageManager();
5748
5749            final int N = mRecentTasks.size();
5750            ArrayList<ActivityManager.RecentTaskInfo> res
5751                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5752                            maxNum < N ? maxNum : N);
5753            for (int i=0; i<N && maxNum > 0; i++) {
5754                TaskRecord tr = mRecentTasks.get(i);
5755                // Only add calling user's recent tasks
5756                if (tr.userId != userId) continue;
5757                // Return the entry if desired by the caller.  We always return
5758                // the first entry, because callers always expect this to be the
5759                // foreground app.  We may filter others if the caller has
5760                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5761                // we should exclude the entry.
5762
5763                if (i == 0
5764                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5765                        || (tr.intent == null)
5766                        || ((tr.intent.getFlags()
5767                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5768                    ActivityManager.RecentTaskInfo rti
5769                            = new ActivityManager.RecentTaskInfo();
5770                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5771                    rti.persistentId = tr.taskId;
5772                    rti.baseIntent = new Intent(
5773                            tr.intent != null ? tr.intent : tr.affinityIntent);
5774                    if (!detailed) {
5775                        rti.baseIntent.replaceExtras((Bundle)null);
5776                    }
5777                    rti.origActivity = tr.origActivity;
5778                    rti.description = tr.lastDescription;
5779
5780                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5781                        // Check whether this activity is currently available.
5782                        try {
5783                            if (rti.origActivity != null) {
5784                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5785                                        == null) {
5786                                    continue;
5787                                }
5788                            } else if (rti.baseIntent != null) {
5789                                if (pm.queryIntentActivities(rti.baseIntent,
5790                                        null, 0, userId) == null) {
5791                                    continue;
5792                                }
5793                            }
5794                        } catch (RemoteException e) {
5795                            // Will never happen.
5796                        }
5797                    }
5798
5799                    res.add(rti);
5800                    maxNum--;
5801                }
5802            }
5803            return res;
5804        }
5805    }
5806
5807    private TaskRecord taskForIdLocked(int id) {
5808        final int N = mRecentTasks.size();
5809        for (int i=0; i<N; i++) {
5810            TaskRecord tr = mRecentTasks.get(i);
5811            if (tr.taskId == id) {
5812                return tr;
5813            }
5814        }
5815        return null;
5816    }
5817
5818    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5819        synchronized (this) {
5820            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5821                    "getTaskThumbnails()");
5822            TaskRecord tr = taskForIdLocked(id);
5823            if (tr != null) {
5824                return mMainStack.getTaskThumbnailsLocked(tr);
5825            }
5826        }
5827        return null;
5828    }
5829
5830    public Bitmap getTaskTopThumbnail(int id) {
5831        synchronized (this) {
5832            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5833                    "getTaskTopThumbnail()");
5834            TaskRecord tr = taskForIdLocked(id);
5835            if (tr != null) {
5836                return mMainStack.getTaskTopThumbnailLocked(tr);
5837            }
5838        }
5839        return null;
5840    }
5841
5842    public boolean removeSubTask(int taskId, int subTaskIndex) {
5843        synchronized (this) {
5844            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5845                    "removeSubTask()");
5846            long ident = Binder.clearCallingIdentity();
5847            try {
5848                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5849                        true) != null;
5850            } finally {
5851                Binder.restoreCallingIdentity(ident);
5852            }
5853        }
5854    }
5855
5856    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5857        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5858        Intent baseIntent = new Intent(
5859                tr.intent != null ? tr.intent : tr.affinityIntent);
5860        ComponentName component = baseIntent.getComponent();
5861        if (component == null) {
5862            Slog.w(TAG, "Now component for base intent of task: " + tr);
5863            return;
5864        }
5865
5866        // Find any running services associated with this app.
5867        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5868
5869        if (killProcesses) {
5870            // Find any running processes associated with this app.
5871            final String pkg = component.getPackageName();
5872            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5873            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5874            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5875                for (int i=0; i<uids.size(); i++) {
5876                    ProcessRecord proc = uids.valueAt(i);
5877                    if (proc.userId != tr.userId) {
5878                        continue;
5879                    }
5880                    if (!proc.pkgList.contains(pkg)) {
5881                        continue;
5882                    }
5883                    procs.add(proc);
5884                }
5885            }
5886
5887            // Kill the running processes.
5888            for (int i=0; i<procs.size(); i++) {
5889                ProcessRecord pr = procs.get(i);
5890                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5891                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5892                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5893                            pr.processName, pr.setAdj, "remove task");
5894                    pr.killedBackground = true;
5895                    Process.killProcessQuiet(pr.pid);
5896                } else {
5897                    pr.waitingToKill = "remove task";
5898                }
5899            }
5900        }
5901    }
5902
5903    public boolean removeTask(int taskId, int flags) {
5904        synchronized (this) {
5905            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5906                    "removeTask()");
5907            long ident = Binder.clearCallingIdentity();
5908            try {
5909                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5910                        false);
5911                if (r != null) {
5912                    mRecentTasks.remove(r.task);
5913                    cleanUpRemovedTaskLocked(r.task, flags);
5914                    return true;
5915                } else {
5916                    TaskRecord tr = null;
5917                    int i=0;
5918                    while (i < mRecentTasks.size()) {
5919                        TaskRecord t = mRecentTasks.get(i);
5920                        if (t.taskId == taskId) {
5921                            tr = t;
5922                            break;
5923                        }
5924                        i++;
5925                    }
5926                    if (tr != null) {
5927                        if (tr.numActivities <= 0) {
5928                            // Caller is just removing a recent task that is
5929                            // not actively running.  That is easy!
5930                            mRecentTasks.remove(i);
5931                            cleanUpRemovedTaskLocked(tr, flags);
5932                            return true;
5933                        } else {
5934                            Slog.w(TAG, "removeTask: task " + taskId
5935                                    + " does not have activities to remove, "
5936                                    + " but numActivities=" + tr.numActivities
5937                                    + ": " + tr);
5938                        }
5939                    }
5940                }
5941            } finally {
5942                Binder.restoreCallingIdentity(ident);
5943            }
5944        }
5945        return false;
5946    }
5947
5948    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5949        int j;
5950        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5951        TaskRecord jt = startTask;
5952
5953        // First look backwards
5954        for (j=startIndex-1; j>=0; j--) {
5955            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5956            if (r.task != jt) {
5957                jt = r.task;
5958                if (affinity.equals(jt.affinity)) {
5959                    return j;
5960                }
5961            }
5962        }
5963
5964        // Now look forwards
5965        final int N = mMainStack.mHistory.size();
5966        jt = startTask;
5967        for (j=startIndex+1; j<N; j++) {
5968            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5969            if (r.task != jt) {
5970                if (affinity.equals(jt.affinity)) {
5971                    return j;
5972                }
5973                jt = r.task;
5974            }
5975        }
5976
5977        // Might it be at the top?
5978        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5979            return N-1;
5980        }
5981
5982        return -1;
5983    }
5984
5985    /**
5986     * TODO: Add mController hook
5987     */
5988    public void moveTaskToFront(int task, int flags, Bundle options) {
5989        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5990                "moveTaskToFront()");
5991
5992        synchronized(this) {
5993            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5994                    Binder.getCallingUid(), "Task to front")) {
5995                ActivityOptions.abort(options);
5996                return;
5997            }
5998            final long origId = Binder.clearCallingIdentity();
5999            try {
6000                TaskRecord tr = taskForIdLocked(task);
6001                if (tr != null) {
6002                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6003                        mMainStack.mUserLeaving = true;
6004                    }
6005                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6006                        // Caller wants the home activity moved with it.  To accomplish this,
6007                        // we'll just move the home task to the top first.
6008                        mMainStack.moveHomeToFrontLocked();
6009                    }
6010                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6011                    return;
6012                }
6013                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6014                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6015                    if (hr.task.taskId == task) {
6016                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6017                            mMainStack.mUserLeaving = true;
6018                        }
6019                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6020                            // Caller wants the home activity moved with it.  To accomplish this,
6021                            // we'll just move the home task to the top first.
6022                            mMainStack.moveHomeToFrontLocked();
6023                        }
6024                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6025                        return;
6026                    }
6027                }
6028            } finally {
6029                Binder.restoreCallingIdentity(origId);
6030            }
6031            ActivityOptions.abort(options);
6032        }
6033    }
6034
6035    public void moveTaskToBack(int task) {
6036        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6037                "moveTaskToBack()");
6038
6039        synchronized(this) {
6040            if (mMainStack.mResumedActivity != null
6041                    && mMainStack.mResumedActivity.task.taskId == task) {
6042                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6043                        Binder.getCallingUid(), "Task to back")) {
6044                    return;
6045                }
6046            }
6047            final long origId = Binder.clearCallingIdentity();
6048            mMainStack.moveTaskToBackLocked(task, null);
6049            Binder.restoreCallingIdentity(origId);
6050        }
6051    }
6052
6053    /**
6054     * Moves an activity, and all of the other activities within the same task, to the bottom
6055     * of the history stack.  The activity's order within the task is unchanged.
6056     *
6057     * @param token A reference to the activity we wish to move
6058     * @param nonRoot If false then this only works if the activity is the root
6059     *                of a task; if true it will work for any activity in a task.
6060     * @return Returns true if the move completed, false if not.
6061     */
6062    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6063        enforceNotIsolatedCaller("moveActivityTaskToBack");
6064        synchronized(this) {
6065            final long origId = Binder.clearCallingIdentity();
6066            int taskId = getTaskForActivityLocked(token, !nonRoot);
6067            if (taskId >= 0) {
6068                return mMainStack.moveTaskToBackLocked(taskId, null);
6069            }
6070            Binder.restoreCallingIdentity(origId);
6071        }
6072        return false;
6073    }
6074
6075    public void moveTaskBackwards(int task) {
6076        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6077                "moveTaskBackwards()");
6078
6079        synchronized(this) {
6080            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6081                    Binder.getCallingUid(), "Task backwards")) {
6082                return;
6083            }
6084            final long origId = Binder.clearCallingIdentity();
6085            moveTaskBackwardsLocked(task);
6086            Binder.restoreCallingIdentity(origId);
6087        }
6088    }
6089
6090    private final void moveTaskBackwardsLocked(int task) {
6091        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6092    }
6093
6094    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6095        synchronized(this) {
6096            return getTaskForActivityLocked(token, onlyRoot);
6097        }
6098    }
6099
6100    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6101        final int N = mMainStack.mHistory.size();
6102        TaskRecord lastTask = null;
6103        for (int i=0; i<N; i++) {
6104            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6105            if (r.appToken == token) {
6106                if (!onlyRoot || lastTask != r.task) {
6107                    return r.task.taskId;
6108                }
6109                return -1;
6110            }
6111            lastTask = r.task;
6112        }
6113
6114        return -1;
6115    }
6116
6117    // =========================================================
6118    // THUMBNAILS
6119    // =========================================================
6120
6121    public void reportThumbnail(IBinder token,
6122            Bitmap thumbnail, CharSequence description) {
6123        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6124        final long origId = Binder.clearCallingIdentity();
6125        sendPendingThumbnail(null, token, thumbnail, description, true);
6126        Binder.restoreCallingIdentity(origId);
6127    }
6128
6129    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6130            Bitmap thumbnail, CharSequence description, boolean always) {
6131        TaskRecord task = null;
6132        ArrayList receivers = null;
6133
6134        //System.out.println("Send pending thumbnail: " + r);
6135
6136        synchronized(this) {
6137            if (r == null) {
6138                r = mMainStack.isInStackLocked(token);
6139                if (r == null) {
6140                    return;
6141                }
6142            }
6143            if (thumbnail == null && r.thumbHolder != null) {
6144                thumbnail = r.thumbHolder.lastThumbnail;
6145                description = r.thumbHolder.lastDescription;
6146            }
6147            if (thumbnail == null && !always) {
6148                // If there is no thumbnail, and this entry is not actually
6149                // going away, then abort for now and pick up the next
6150                // thumbnail we get.
6151                return;
6152            }
6153            task = r.task;
6154
6155            int N = mPendingThumbnails.size();
6156            int i=0;
6157            while (i<N) {
6158                PendingThumbnailsRecord pr =
6159                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6160                //System.out.println("Looking in " + pr.pendingRecords);
6161                if (pr.pendingRecords.remove(r)) {
6162                    if (receivers == null) {
6163                        receivers = new ArrayList();
6164                    }
6165                    receivers.add(pr);
6166                    if (pr.pendingRecords.size() == 0) {
6167                        pr.finished = true;
6168                        mPendingThumbnails.remove(i);
6169                        N--;
6170                        continue;
6171                    }
6172                }
6173                i++;
6174            }
6175        }
6176
6177        if (receivers != null) {
6178            final int N = receivers.size();
6179            for (int i=0; i<N; i++) {
6180                try {
6181                    PendingThumbnailsRecord pr =
6182                        (PendingThumbnailsRecord)receivers.get(i);
6183                    pr.receiver.newThumbnail(
6184                        task != null ? task.taskId : -1, thumbnail, description);
6185                    if (pr.finished) {
6186                        pr.receiver.finished();
6187                    }
6188                } catch (Exception e) {
6189                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6190                }
6191            }
6192        }
6193    }
6194
6195    // =========================================================
6196    // CONTENT PROVIDERS
6197    // =========================================================
6198
6199    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6200        List<ProviderInfo> providers = null;
6201        try {
6202            providers = AppGlobals.getPackageManager().
6203                queryContentProviders(app.processName, app.uid,
6204                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6205        } catch (RemoteException ex) {
6206        }
6207        if (DEBUG_MU)
6208            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6209        int userId = app.userId;
6210        if (providers != null) {
6211            int N = providers.size();
6212            for (int i=0; i<N; i++) {
6213                ProviderInfo cpi =
6214                    (ProviderInfo)providers.get(i);
6215                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6216                        cpi.name, cpi.flags);
6217                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6218                    // This is a singleton provider, but a user besides the
6219                    // default user is asking to initialize a process it runs
6220                    // in...  well, no, it doesn't actually run in this process,
6221                    // it runs in the process of the default user.  Get rid of it.
6222                    providers.remove(i);
6223                    N--;
6224                    continue;
6225                }
6226
6227                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6228                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6229                if (cpr == null) {
6230                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6231                    mProviderMap.putProviderByClass(comp, cpr);
6232                }
6233                if (DEBUG_MU)
6234                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6235                app.pubProviders.put(cpi.name, cpr);
6236                app.addPackage(cpi.applicationInfo.packageName);
6237                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6238            }
6239        }
6240        return providers;
6241    }
6242
6243    /**
6244     * Check if {@link ProcessRecord} has a possible chance at accessing the
6245     * given {@link ProviderInfo}. Final permission checking is always done
6246     * in {@link ContentProvider}.
6247     */
6248    private final String checkContentProviderPermissionLocked(
6249            ProviderInfo cpi, ProcessRecord r) {
6250        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6251        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6252        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6253                cpi.applicationInfo.uid, cpi.exported)
6254                == PackageManager.PERMISSION_GRANTED) {
6255            return null;
6256        }
6257        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6258                cpi.applicationInfo.uid, cpi.exported)
6259                == PackageManager.PERMISSION_GRANTED) {
6260            return null;
6261        }
6262
6263        PathPermission[] pps = cpi.pathPermissions;
6264        if (pps != null) {
6265            int i = pps.length;
6266            while (i > 0) {
6267                i--;
6268                PathPermission pp = pps[i];
6269                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6270                        cpi.applicationInfo.uid, cpi.exported)
6271                        == PackageManager.PERMISSION_GRANTED) {
6272                    return null;
6273                }
6274                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6275                        cpi.applicationInfo.uid, cpi.exported)
6276                        == PackageManager.PERMISSION_GRANTED) {
6277                    return null;
6278                }
6279            }
6280        }
6281
6282        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6283        if (perms != null) {
6284            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6285                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6286                    return null;
6287                }
6288            }
6289        }
6290
6291        String msg;
6292        if (!cpi.exported) {
6293            msg = "Permission Denial: opening provider " + cpi.name
6294                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6295                    + ", uid=" + callingUid + ") that is not exported from uid "
6296                    + cpi.applicationInfo.uid;
6297        } else {
6298            msg = "Permission Denial: opening provider " + cpi.name
6299                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6300                    + ", uid=" + callingUid + ") requires "
6301                    + cpi.readPermission + " or " + cpi.writePermission;
6302        }
6303        Slog.w(TAG, msg);
6304        return msg;
6305    }
6306
6307    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6308            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6309        if (r != null) {
6310            for (int i=0; i<r.conProviders.size(); i++) {
6311                ContentProviderConnection conn = r.conProviders.get(i);
6312                if (conn.provider == cpr) {
6313                    if (DEBUG_PROVIDER) Slog.v(TAG,
6314                            "Adding provider requested by "
6315                            + r.processName + " from process "
6316                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6317                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6318                    if (stable) {
6319                        conn.stableCount++;
6320                        conn.numStableIncs++;
6321                    } else {
6322                        conn.unstableCount++;
6323                        conn.numUnstableIncs++;
6324                    }
6325                    return conn;
6326                }
6327            }
6328            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6329            if (stable) {
6330                conn.stableCount = 1;
6331                conn.numStableIncs = 1;
6332            } else {
6333                conn.unstableCount = 1;
6334                conn.numUnstableIncs = 1;
6335            }
6336            cpr.connections.add(conn);
6337            r.conProviders.add(conn);
6338            return conn;
6339        }
6340        cpr.addExternalProcessHandleLocked(externalProcessToken);
6341        return null;
6342    }
6343
6344    boolean decProviderCountLocked(ContentProviderConnection conn,
6345            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6346        if (conn != null) {
6347            cpr = conn.provider;
6348            if (DEBUG_PROVIDER) Slog.v(TAG,
6349                    "Removing provider requested by "
6350                    + conn.client.processName + " from process "
6351                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6352                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6353            if (stable) {
6354                conn.stableCount--;
6355            } else {
6356                conn.unstableCount--;
6357            }
6358            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6359                cpr.connections.remove(conn);
6360                conn.client.conProviders.remove(conn);
6361                return true;
6362            }
6363            return false;
6364        }
6365        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6366        return false;
6367    }
6368
6369    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6370            String name, IBinder token, boolean stable, int userId) {
6371        ContentProviderRecord cpr;
6372        ContentProviderConnection conn = null;
6373        ProviderInfo cpi = null;
6374
6375        synchronized(this) {
6376            ProcessRecord r = null;
6377            if (caller != null) {
6378                r = getRecordForAppLocked(caller);
6379                if (r == null) {
6380                    throw new SecurityException(
6381                            "Unable to find app for caller " + caller
6382                          + " (pid=" + Binder.getCallingPid()
6383                          + ") when getting content provider " + name);
6384                }
6385            }
6386
6387            // First check if this content provider has been published...
6388            cpr = mProviderMap.getProviderByName(name, userId);
6389            boolean providerRunning = cpr != null;
6390            if (providerRunning) {
6391                cpi = cpr.info;
6392                String msg;
6393                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6394                    throw new SecurityException(msg);
6395                }
6396
6397                if (r != null && cpr.canRunHere(r)) {
6398                    // This provider has been published or is in the process
6399                    // of being published...  but it is also allowed to run
6400                    // in the caller's process, so don't make a connection
6401                    // and just let the caller instantiate its own instance.
6402                    ContentProviderHolder holder = cpr.newHolder(null);
6403                    // don't give caller the provider object, it needs
6404                    // to make its own.
6405                    holder.provider = null;
6406                    return holder;
6407                }
6408
6409                final long origId = Binder.clearCallingIdentity();
6410
6411                // In this case the provider instance already exists, so we can
6412                // return it right away.
6413                conn = incProviderCountLocked(r, cpr, token, stable);
6414                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6415                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6416                        // If this is a perceptible app accessing the provider,
6417                        // make sure to count it as being accessed and thus
6418                        // back up on the LRU list.  This is good because
6419                        // content providers are often expensive to start.
6420                        updateLruProcessLocked(cpr.proc, false);
6421                    }
6422                }
6423
6424                if (cpr.proc != null) {
6425                    if (false) {
6426                        if (cpr.name.flattenToShortString().equals(
6427                                "com.android.providers.calendar/.CalendarProvider2")) {
6428                            Slog.v(TAG, "****************** KILLING "
6429                                + cpr.name.flattenToShortString());
6430                            Process.killProcess(cpr.proc.pid);
6431                        }
6432                    }
6433                    boolean success = updateOomAdjLocked(cpr.proc);
6434                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6435                    // NOTE: there is still a race here where a signal could be
6436                    // pending on the process even though we managed to update its
6437                    // adj level.  Not sure what to do about this, but at least
6438                    // the race is now smaller.
6439                    if (!success) {
6440                        // Uh oh...  it looks like the provider's process
6441                        // has been killed on us.  We need to wait for a new
6442                        // process to be started, and make sure its death
6443                        // doesn't kill our process.
6444                        Slog.i(TAG,
6445                                "Existing provider " + cpr.name.flattenToShortString()
6446                                + " is crashing; detaching " + r);
6447                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6448                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6449                        if (!lastRef) {
6450                            // This wasn't the last ref our process had on
6451                            // the provider...  we have now been killed, bail.
6452                            return null;
6453                        }
6454                        providerRunning = false;
6455                        conn = null;
6456                    }
6457                }
6458
6459                Binder.restoreCallingIdentity(origId);
6460            }
6461
6462            boolean singleton;
6463            if (!providerRunning) {
6464                try {
6465                    cpi = AppGlobals.getPackageManager().
6466                        resolveContentProvider(name,
6467                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6468                } catch (RemoteException ex) {
6469                }
6470                if (cpi == null) {
6471                    return null;
6472                }
6473                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6474                        cpi.name, cpi.flags);
6475                if (singleton) {
6476                    userId = 0;
6477                }
6478                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6479
6480                String msg;
6481                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6482                    throw new SecurityException(msg);
6483                }
6484
6485                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6486                        && !cpi.processName.equals("system")) {
6487                    // If this content provider does not run in the system
6488                    // process, and the system is not yet ready to run other
6489                    // processes, then fail fast instead of hanging.
6490                    throw new IllegalArgumentException(
6491                            "Attempt to launch content provider before system ready");
6492                }
6493
6494                // Make sure that the user who owns this provider is started.  If not,
6495                // we don't want to allow it to run.
6496                if (mStartedUsers.get(userId) == null) {
6497                    Slog.w(TAG, "Unable to launch app "
6498                            + cpi.applicationInfo.packageName + "/"
6499                            + cpi.applicationInfo.uid + " for provider "
6500                            + name + ": user " + userId + " is stopped");
6501                    return null;
6502                }
6503
6504                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6505                cpr = mProviderMap.getProviderByClass(comp, userId);
6506                final boolean firstClass = cpr == null;
6507                if (firstClass) {
6508                    try {
6509                        ApplicationInfo ai =
6510                            AppGlobals.getPackageManager().
6511                                getApplicationInfo(
6512                                        cpi.applicationInfo.packageName,
6513                                        STOCK_PM_FLAGS, userId);
6514                        if (ai == null) {
6515                            Slog.w(TAG, "No package info for content provider "
6516                                    + cpi.name);
6517                            return null;
6518                        }
6519                        ai = getAppInfoForUser(ai, userId);
6520                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6521                    } catch (RemoteException ex) {
6522                        // pm is in same process, this will never happen.
6523                    }
6524                }
6525
6526                if (r != null && cpr.canRunHere(r)) {
6527                    // If this is a multiprocess provider, then just return its
6528                    // info and allow the caller to instantiate it.  Only do
6529                    // this if the provider is the same user as the caller's
6530                    // process, or can run as root (so can be in any process).
6531                    return cpr.newHolder(null);
6532                }
6533
6534                if (DEBUG_PROVIDER) {
6535                    RuntimeException e = new RuntimeException("here");
6536                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6537                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6538                }
6539
6540                // This is single process, and our app is now connecting to it.
6541                // See if we are already in the process of launching this
6542                // provider.
6543                final int N = mLaunchingProviders.size();
6544                int i;
6545                for (i=0; i<N; i++) {
6546                    if (mLaunchingProviders.get(i) == cpr) {
6547                        break;
6548                    }
6549                }
6550
6551                // If the provider is not already being launched, then get it
6552                // started.
6553                if (i >= N) {
6554                    final long origId = Binder.clearCallingIdentity();
6555
6556                    try {
6557                        // Content provider is now in use, its package can't be stopped.
6558                        try {
6559                            AppGlobals.getPackageManager().setPackageStoppedState(
6560                                    cpr.appInfo.packageName, false, userId);
6561                        } catch (RemoteException e) {
6562                        } catch (IllegalArgumentException e) {
6563                            Slog.w(TAG, "Failed trying to unstop package "
6564                                    + cpr.appInfo.packageName + ": " + e);
6565                        }
6566
6567                        ProcessRecord proc = startProcessLocked(cpi.processName,
6568                                cpr.appInfo, false, 0, "content provider",
6569                                new ComponentName(cpi.applicationInfo.packageName,
6570                                        cpi.name), false, false);
6571                        if (proc == null) {
6572                            Slog.w(TAG, "Unable to launch app "
6573                                    + cpi.applicationInfo.packageName + "/"
6574                                    + cpi.applicationInfo.uid + " for provider "
6575                                    + name + ": process is bad");
6576                            return null;
6577                        }
6578                        cpr.launchingApp = proc;
6579                        mLaunchingProviders.add(cpr);
6580                    } finally {
6581                        Binder.restoreCallingIdentity(origId);
6582                    }
6583                }
6584
6585                // Make sure the provider is published (the same provider class
6586                // may be published under multiple names).
6587                if (firstClass) {
6588                    mProviderMap.putProviderByClass(comp, cpr);
6589                }
6590
6591                mProviderMap.putProviderByName(name, cpr);
6592                conn = incProviderCountLocked(r, cpr, token, stable);
6593                if (conn != null) {
6594                    conn.waiting = true;
6595                }
6596            }
6597        }
6598
6599        // Wait for the provider to be published...
6600        synchronized (cpr) {
6601            while (cpr.provider == null) {
6602                if (cpr.launchingApp == null) {
6603                    Slog.w(TAG, "Unable to launch app "
6604                            + cpi.applicationInfo.packageName + "/"
6605                            + cpi.applicationInfo.uid + " for provider "
6606                            + name + ": launching app became null");
6607                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6608                            UserHandle.getUserId(cpi.applicationInfo.uid),
6609                            cpi.applicationInfo.packageName,
6610                            cpi.applicationInfo.uid, name);
6611                    return null;
6612                }
6613                try {
6614                    if (DEBUG_MU) {
6615                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6616                                + cpr.launchingApp);
6617                    }
6618                    if (conn != null) {
6619                        conn.waiting = true;
6620                    }
6621                    cpr.wait();
6622                } catch (InterruptedException ex) {
6623                } finally {
6624                    if (conn != null) {
6625                        conn.waiting = false;
6626                    }
6627                }
6628            }
6629        }
6630        return cpr != null ? cpr.newHolder(conn) : null;
6631    }
6632
6633    public final ContentProviderHolder getContentProvider(
6634            IApplicationThread caller, String name, int userId, boolean stable) {
6635        enforceNotIsolatedCaller("getContentProvider");
6636        if (caller == null) {
6637            String msg = "null IApplicationThread when getting content provider "
6638                    + name;
6639            Slog.w(TAG, msg);
6640            throw new SecurityException(msg);
6641        }
6642
6643        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6644                false, true, "getContentProvider", null);
6645        return getContentProviderImpl(caller, name, null, stable, userId);
6646    }
6647
6648    public ContentProviderHolder getContentProviderExternal(
6649            String name, int userId, IBinder token) {
6650        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6651            "Do not have permission in call getContentProviderExternal()");
6652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6653                false, true, "getContentProvider", null);
6654        return getContentProviderExternalUnchecked(name, token, userId);
6655    }
6656
6657    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6658            IBinder token, int userId) {
6659        return getContentProviderImpl(null, name, token, true, userId);
6660    }
6661
6662    /**
6663     * Drop a content provider from a ProcessRecord's bookkeeping
6664     * @param cpr
6665     */
6666    public void removeContentProvider(IBinder connection, boolean stable) {
6667        enforceNotIsolatedCaller("removeContentProvider");
6668        synchronized (this) {
6669            ContentProviderConnection conn;
6670            try {
6671                conn = (ContentProviderConnection)connection;
6672            } catch (ClassCastException e) {
6673                String msg ="removeContentProvider: " + connection
6674                        + " not a ContentProviderConnection";
6675                Slog.w(TAG, msg);
6676                throw new IllegalArgumentException(msg);
6677            }
6678            if (conn == null) {
6679                throw new NullPointerException("connection is null");
6680            }
6681            if (decProviderCountLocked(conn, null, null, stable)) {
6682                updateOomAdjLocked();
6683            }
6684        }
6685    }
6686
6687    public void removeContentProviderExternal(String name, IBinder token) {
6688        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6689            "Do not have permission in call removeContentProviderExternal()");
6690        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6691    }
6692
6693    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6694        synchronized (this) {
6695            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6696            if(cpr == null) {
6697                //remove from mProvidersByClass
6698                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6699                return;
6700            }
6701
6702            //update content provider record entry info
6703            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6704            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6705            if (localCpr.hasExternalProcessHandles()) {
6706                if (localCpr.removeExternalProcessHandleLocked(token)) {
6707                    updateOomAdjLocked();
6708                } else {
6709                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6710                            + " with no external reference for token: "
6711                            + token + ".");
6712                }
6713            } else {
6714                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6715                        + " with no external references.");
6716            }
6717        }
6718    }
6719
6720    public final void publishContentProviders(IApplicationThread caller,
6721            List<ContentProviderHolder> providers) {
6722        if (providers == null) {
6723            return;
6724        }
6725
6726        enforceNotIsolatedCaller("publishContentProviders");
6727        synchronized (this) {
6728            final ProcessRecord r = getRecordForAppLocked(caller);
6729            if (DEBUG_MU)
6730                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6731            if (r == null) {
6732                throw new SecurityException(
6733                        "Unable to find app for caller " + caller
6734                      + " (pid=" + Binder.getCallingPid()
6735                      + ") when publishing content providers");
6736            }
6737
6738            final long origId = Binder.clearCallingIdentity();
6739
6740            final int N = providers.size();
6741            for (int i=0; i<N; i++) {
6742                ContentProviderHolder src = providers.get(i);
6743                if (src == null || src.info == null || src.provider == null) {
6744                    continue;
6745                }
6746                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6747                if (DEBUG_MU)
6748                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6749                if (dst != null) {
6750                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6751                    mProviderMap.putProviderByClass(comp, dst);
6752                    String names[] = dst.info.authority.split(";");
6753                    for (int j = 0; j < names.length; j++) {
6754                        mProviderMap.putProviderByName(names[j], dst);
6755                    }
6756
6757                    int NL = mLaunchingProviders.size();
6758                    int j;
6759                    for (j=0; j<NL; j++) {
6760                        if (mLaunchingProviders.get(j) == dst) {
6761                            mLaunchingProviders.remove(j);
6762                            j--;
6763                            NL--;
6764                        }
6765                    }
6766                    synchronized (dst) {
6767                        dst.provider = src.provider;
6768                        dst.proc = r;
6769                        dst.notifyAll();
6770                    }
6771                    updateOomAdjLocked(r);
6772                }
6773            }
6774
6775            Binder.restoreCallingIdentity(origId);
6776        }
6777    }
6778
6779    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6780        ContentProviderConnection conn;
6781        try {
6782            conn = (ContentProviderConnection)connection;
6783        } catch (ClassCastException e) {
6784            String msg ="refContentProvider: " + connection
6785                    + " not a ContentProviderConnection";
6786            Slog.w(TAG, msg);
6787            throw new IllegalArgumentException(msg);
6788        }
6789        if (conn == null) {
6790            throw new NullPointerException("connection is null");
6791        }
6792
6793        synchronized (this) {
6794            if (stable > 0) {
6795                conn.numStableIncs += stable;
6796            }
6797            stable = conn.stableCount + stable;
6798            if (stable < 0) {
6799                throw new IllegalStateException("stableCount < 0: " + stable);
6800            }
6801
6802            if (unstable > 0) {
6803                conn.numUnstableIncs += unstable;
6804            }
6805            unstable = conn.unstableCount + unstable;
6806            if (unstable < 0) {
6807                throw new IllegalStateException("unstableCount < 0: " + unstable);
6808            }
6809
6810            if ((stable+unstable) <= 0) {
6811                throw new IllegalStateException("ref counts can't go to zero here: stable="
6812                        + stable + " unstable=" + unstable);
6813            }
6814            conn.stableCount = stable;
6815            conn.unstableCount = unstable;
6816            return !conn.dead;
6817        }
6818    }
6819
6820    public void unstableProviderDied(IBinder connection) {
6821        ContentProviderConnection conn;
6822        try {
6823            conn = (ContentProviderConnection)connection;
6824        } catch (ClassCastException e) {
6825            String msg ="refContentProvider: " + connection
6826                    + " not a ContentProviderConnection";
6827            Slog.w(TAG, msg);
6828            throw new IllegalArgumentException(msg);
6829        }
6830        if (conn == null) {
6831            throw new NullPointerException("connection is null");
6832        }
6833
6834        // Safely retrieve the content provider associated with the connection.
6835        IContentProvider provider;
6836        synchronized (this) {
6837            provider = conn.provider.provider;
6838        }
6839
6840        if (provider == null) {
6841            // Um, yeah, we're way ahead of you.
6842            return;
6843        }
6844
6845        // Make sure the caller is being honest with us.
6846        if (provider.asBinder().pingBinder()) {
6847            // Er, no, still looks good to us.
6848            synchronized (this) {
6849                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6850                        + " says " + conn + " died, but we don't agree");
6851                return;
6852            }
6853        }
6854
6855        // Well look at that!  It's dead!
6856        synchronized (this) {
6857            if (conn.provider.provider != provider) {
6858                // But something changed...  good enough.
6859                return;
6860            }
6861
6862            ProcessRecord proc = conn.provider.proc;
6863            if (proc == null || proc.thread == null) {
6864                // Seems like the process is already cleaned up.
6865                return;
6866            }
6867
6868            // As far as we're concerned, this is just like receiving a
6869            // death notification...  just a bit prematurely.
6870            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6871                    + ") early provider death");
6872            final long ident = Binder.clearCallingIdentity();
6873            try {
6874                appDiedLocked(proc, proc.pid, proc.thread);
6875            } finally {
6876                Binder.restoreCallingIdentity(ident);
6877            }
6878        }
6879    }
6880
6881    public static final void installSystemProviders() {
6882        List<ProviderInfo> providers;
6883        synchronized (mSelf) {
6884            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6885            providers = mSelf.generateApplicationProvidersLocked(app);
6886            if (providers != null) {
6887                for (int i=providers.size()-1; i>=0; i--) {
6888                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6889                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6890                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6891                                + ": not system .apk");
6892                        providers.remove(i);
6893                    }
6894                }
6895            }
6896        }
6897        if (providers != null) {
6898            mSystemThread.installSystemProviders(providers);
6899        }
6900
6901        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6902
6903        mSelf.mUsageStatsService.monitorPackages();
6904    }
6905
6906    /**
6907     * Allows app to retrieve the MIME type of a URI without having permission
6908     * to access its content provider.
6909     *
6910     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6911     *
6912     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6913     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6914     */
6915    public String getProviderMimeType(Uri uri, int userId) {
6916        enforceNotIsolatedCaller("getProviderMimeType");
6917        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6918                userId, false, true, "getProviderMimeType", null);
6919        final String name = uri.getAuthority();
6920        final long ident = Binder.clearCallingIdentity();
6921        ContentProviderHolder holder = null;
6922
6923        try {
6924            holder = getContentProviderExternalUnchecked(name, null, userId);
6925            if (holder != null) {
6926                return holder.provider.getType(uri);
6927            }
6928        } catch (RemoteException e) {
6929            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6930            return null;
6931        } finally {
6932            if (holder != null) {
6933                removeContentProviderExternalUnchecked(name, null, userId);
6934            }
6935            Binder.restoreCallingIdentity(ident);
6936        }
6937
6938        return null;
6939    }
6940
6941    // =========================================================
6942    // GLOBAL MANAGEMENT
6943    // =========================================================
6944
6945    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6946            ApplicationInfo info, String customProcess, boolean isolated) {
6947        String proc = customProcess != null ? customProcess : info.processName;
6948        BatteryStatsImpl.Uid.Proc ps = null;
6949        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6950        int uid = info.uid;
6951        if (isolated) {
6952            int userId = UserHandle.getUserId(uid);
6953            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6954            uid = 0;
6955            while (true) {
6956                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6957                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6958                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6959                }
6960                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6961                mNextIsolatedProcessUid++;
6962                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6963                    // No process for this uid, use it.
6964                    break;
6965                }
6966                stepsLeft--;
6967                if (stepsLeft <= 0) {
6968                    return null;
6969                }
6970            }
6971        }
6972        synchronized (stats) {
6973            ps = stats.getProcessStatsLocked(info.uid, proc);
6974        }
6975        return new ProcessRecord(ps, thread, info, proc, uid);
6976    }
6977
6978    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6979        ProcessRecord app;
6980        if (!isolated) {
6981            app = getProcessRecordLocked(info.processName, info.uid);
6982        } else {
6983            app = null;
6984        }
6985
6986        if (app == null) {
6987            app = newProcessRecordLocked(null, info, null, isolated);
6988            mProcessNames.put(info.processName, app.uid, app);
6989            if (isolated) {
6990                mIsolatedProcesses.put(app.uid, app);
6991            }
6992            updateLruProcessLocked(app, true);
6993        }
6994
6995        // This package really, really can not be stopped.
6996        try {
6997            AppGlobals.getPackageManager().setPackageStoppedState(
6998                    info.packageName, false, UserHandle.getUserId(app.uid));
6999        } catch (RemoteException e) {
7000        } catch (IllegalArgumentException e) {
7001            Slog.w(TAG, "Failed trying to unstop package "
7002                    + info.packageName + ": " + e);
7003        }
7004
7005        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7006                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7007            app.persistent = true;
7008            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7009        }
7010        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7011            mPersistentStartingProcesses.add(app);
7012            startProcessLocked(app, "added application", app.processName);
7013        }
7014
7015        return app;
7016    }
7017
7018    public void unhandledBack() {
7019        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7020                "unhandledBack()");
7021
7022        synchronized(this) {
7023            int count = mMainStack.mHistory.size();
7024            if (DEBUG_SWITCH) Slog.d(
7025                TAG, "Performing unhandledBack(): stack size = " + count);
7026            if (count > 1) {
7027                final long origId = Binder.clearCallingIdentity();
7028                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7029                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7030                Binder.restoreCallingIdentity(origId);
7031            }
7032        }
7033    }
7034
7035    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7036        enforceNotIsolatedCaller("openContentUri");
7037        final int userId = UserHandle.getCallingUserId();
7038        String name = uri.getAuthority();
7039        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7040        ParcelFileDescriptor pfd = null;
7041        if (cph != null) {
7042            // We record the binder invoker's uid in thread-local storage before
7043            // going to the content provider to open the file.  Later, in the code
7044            // that handles all permissions checks, we look for this uid and use
7045            // that rather than the Activity Manager's own uid.  The effect is that
7046            // we do the check against the caller's permissions even though it looks
7047            // to the content provider like the Activity Manager itself is making
7048            // the request.
7049            sCallerIdentity.set(new Identity(
7050                    Binder.getCallingPid(), Binder.getCallingUid()));
7051            try {
7052                pfd = cph.provider.openFile(uri, "r");
7053            } catch (FileNotFoundException e) {
7054                // do nothing; pfd will be returned null
7055            } finally {
7056                // Ensure that whatever happens, we clean up the identity state
7057                sCallerIdentity.remove();
7058            }
7059
7060            // We've got the fd now, so we're done with the provider.
7061            removeContentProviderExternalUnchecked(name, null, userId);
7062        } else {
7063            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7064        }
7065        return pfd;
7066    }
7067
7068    // Actually is sleeping or shutting down or whatever else in the future
7069    // is an inactive state.
7070    public boolean isSleeping() {
7071        return mSleeping || mShuttingDown;
7072    }
7073
7074    public void goingToSleep() {
7075        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7076                != PackageManager.PERMISSION_GRANTED) {
7077            throw new SecurityException("Requires permission "
7078                    + android.Manifest.permission.DEVICE_POWER);
7079        }
7080
7081        synchronized(this) {
7082            mWentToSleep = true;
7083            updateEventDispatchingLocked();
7084
7085            if (!mSleeping) {
7086                mSleeping = true;
7087                mMainStack.stopIfSleepingLocked();
7088
7089                // Initialize the wake times of all processes.
7090                checkExcessivePowerUsageLocked(false);
7091                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7092                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7093                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7094            }
7095        }
7096    }
7097
7098    public boolean shutdown(int timeout) {
7099        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7100                != PackageManager.PERMISSION_GRANTED) {
7101            throw new SecurityException("Requires permission "
7102                    + android.Manifest.permission.SHUTDOWN);
7103        }
7104
7105        boolean timedout = false;
7106
7107        synchronized(this) {
7108            mShuttingDown = true;
7109            updateEventDispatchingLocked();
7110
7111            if (mMainStack.mResumedActivity != null) {
7112                mMainStack.stopIfSleepingLocked();
7113                final long endTime = System.currentTimeMillis() + timeout;
7114                while (mMainStack.mResumedActivity != null
7115                        || mMainStack.mPausingActivity != null) {
7116                    long delay = endTime - System.currentTimeMillis();
7117                    if (delay <= 0) {
7118                        Slog.w(TAG, "Activity manager shutdown timed out");
7119                        timedout = true;
7120                        break;
7121                    }
7122                    try {
7123                        this.wait();
7124                    } catch (InterruptedException e) {
7125                    }
7126                }
7127            }
7128        }
7129
7130        mUsageStatsService.shutdown();
7131        mBatteryStatsService.shutdown();
7132
7133        return timedout;
7134    }
7135
7136    public final void activitySlept(IBinder token) {
7137        if (localLOGV) Slog.v(
7138            TAG, "Activity slept: token=" + token);
7139
7140        ActivityRecord r = null;
7141
7142        final long origId = Binder.clearCallingIdentity();
7143
7144        synchronized (this) {
7145            r = mMainStack.isInStackLocked(token);
7146            if (r != null) {
7147                mMainStack.activitySleptLocked(r);
7148            }
7149        }
7150
7151        Binder.restoreCallingIdentity(origId);
7152    }
7153
7154    private void comeOutOfSleepIfNeededLocked() {
7155        if (!mWentToSleep && !mLockScreenShown) {
7156            if (mSleeping) {
7157                mSleeping = false;
7158                mMainStack.awakeFromSleepingLocked();
7159                mMainStack.resumeTopActivityLocked(null);
7160            }
7161        }
7162    }
7163
7164    public void wakingUp() {
7165        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7166                != PackageManager.PERMISSION_GRANTED) {
7167            throw new SecurityException("Requires permission "
7168                    + android.Manifest.permission.DEVICE_POWER);
7169        }
7170
7171        synchronized(this) {
7172            mWentToSleep = false;
7173            updateEventDispatchingLocked();
7174            comeOutOfSleepIfNeededLocked();
7175        }
7176    }
7177
7178    private void updateEventDispatchingLocked() {
7179        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7180    }
7181
7182    public void setLockScreenShown(boolean shown) {
7183        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7184                != PackageManager.PERMISSION_GRANTED) {
7185            throw new SecurityException("Requires permission "
7186                    + android.Manifest.permission.DEVICE_POWER);
7187        }
7188
7189        synchronized(this) {
7190            mLockScreenShown = shown;
7191            comeOutOfSleepIfNeededLocked();
7192        }
7193    }
7194
7195    public void stopAppSwitches() {
7196        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7197                != PackageManager.PERMISSION_GRANTED) {
7198            throw new SecurityException("Requires permission "
7199                    + android.Manifest.permission.STOP_APP_SWITCHES);
7200        }
7201
7202        synchronized(this) {
7203            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7204                    + APP_SWITCH_DELAY_TIME;
7205            mDidAppSwitch = false;
7206            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7207            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7208            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7209        }
7210    }
7211
7212    public void resumeAppSwitches() {
7213        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7214                != PackageManager.PERMISSION_GRANTED) {
7215            throw new SecurityException("Requires permission "
7216                    + android.Manifest.permission.STOP_APP_SWITCHES);
7217        }
7218
7219        synchronized(this) {
7220            // Note that we don't execute any pending app switches... we will
7221            // let those wait until either the timeout, or the next start
7222            // activity request.
7223            mAppSwitchesAllowedTime = 0;
7224        }
7225    }
7226
7227    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7228            String name) {
7229        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7230            return true;
7231        }
7232
7233        final int perm = checkComponentPermission(
7234                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7235                callingUid, -1, true);
7236        if (perm == PackageManager.PERMISSION_GRANTED) {
7237            return true;
7238        }
7239
7240        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7241        return false;
7242    }
7243
7244    public void setDebugApp(String packageName, boolean waitForDebugger,
7245            boolean persistent) {
7246        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7247                "setDebugApp()");
7248
7249        // Note that this is not really thread safe if there are multiple
7250        // callers into it at the same time, but that's not a situation we
7251        // care about.
7252        if (persistent) {
7253            final ContentResolver resolver = mContext.getContentResolver();
7254            Settings.Global.putString(
7255                resolver, Settings.Global.DEBUG_APP,
7256                packageName);
7257            Settings.Global.putInt(
7258                resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7259                waitForDebugger ? 1 : 0);
7260        }
7261
7262        synchronized (this) {
7263            if (!persistent) {
7264                mOrigDebugApp = mDebugApp;
7265                mOrigWaitForDebugger = mWaitForDebugger;
7266            }
7267            mDebugApp = packageName;
7268            mWaitForDebugger = waitForDebugger;
7269            mDebugTransient = !persistent;
7270            if (packageName != null) {
7271                final long origId = Binder.clearCallingIdentity();
7272                forceStopPackageLocked(packageName, -1, false, false, true, true,
7273                        UserHandle.USER_ALL);
7274                Binder.restoreCallingIdentity(origId);
7275            }
7276        }
7277    }
7278
7279    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7280        synchronized (this) {
7281            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7282            if (!isDebuggable) {
7283                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7284                    throw new SecurityException("Process not debuggable: " + app.packageName);
7285                }
7286            }
7287
7288            mOpenGlTraceApp = processName;
7289        }
7290    }
7291
7292    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7293            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7294        synchronized (this) {
7295            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7296            if (!isDebuggable) {
7297                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7298                    throw new SecurityException("Process not debuggable: " + app.packageName);
7299                }
7300            }
7301            mProfileApp = processName;
7302            mProfileFile = profileFile;
7303            if (mProfileFd != null) {
7304                try {
7305                    mProfileFd.close();
7306                } catch (IOException e) {
7307                }
7308                mProfileFd = null;
7309            }
7310            mProfileFd = profileFd;
7311            mProfileType = 0;
7312            mAutoStopProfiler = autoStopProfiler;
7313        }
7314    }
7315
7316    public void setAlwaysFinish(boolean enabled) {
7317        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7318                "setAlwaysFinish()");
7319
7320        Settings.Global.putInt(
7321                mContext.getContentResolver(),
7322                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7323
7324        synchronized (this) {
7325            mAlwaysFinishActivities = enabled;
7326        }
7327    }
7328
7329    public void setActivityController(IActivityController controller) {
7330        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7331                "setActivityController()");
7332        synchronized (this) {
7333            mController = controller;
7334        }
7335    }
7336
7337    public boolean isUserAMonkey() {
7338        // For now the fact that there is a controller implies
7339        // we have a monkey.
7340        synchronized (this) {
7341            return mController != null;
7342        }
7343    }
7344
7345    public void requestBugReport() {
7346        // No permission check because this can't do anything harmful --
7347        // it will just eventually cause the user to be presented with
7348        // a UI to select where the bug report goes.
7349        SystemProperties.set("ctl.start", "bugreport");
7350    }
7351
7352    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7353        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7354                != PackageManager.PERMISSION_GRANTED) {
7355            throw new SecurityException("Requires permission "
7356                    + android.Manifest.permission.FILTER_EVENTS);
7357        }
7358
7359        ProcessRecord proc;
7360
7361        // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7362        synchronized (this) {
7363            synchronized (mPidsSelfLocked) {
7364                proc = mPidsSelfLocked.get(pid);
7365            }
7366            if (proc != null) {
7367                if (proc.debugging) {
7368                    return -1;
7369                }
7370
7371                if (mDidDexOpt) {
7372                    // Give more time since we were dexopting.
7373                    mDidDexOpt = false;
7374                    return -1;
7375                }
7376
7377                if (proc.instrumentationClass != null) {
7378                    Bundle info = new Bundle();
7379                    info.putString("shortMsg", "keyDispatchingTimedOut");
7380                    info.putString("longMsg", "Timed out while dispatching key event");
7381                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7382                    proc = null;
7383                }
7384            }
7385        }
7386
7387        if (proc != null) {
7388            appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7389            if (proc.instrumentationClass != null || proc.usingWrapper) {
7390                return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7391            }
7392        }
7393
7394        return KEY_DISPATCHING_TIMEOUT;
7395    }
7396
7397    public void registerProcessObserver(IProcessObserver observer) {
7398        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7399                "registerProcessObserver()");
7400        synchronized (this) {
7401            mProcessObservers.register(observer);
7402        }
7403    }
7404
7405    public void unregisterProcessObserver(IProcessObserver observer) {
7406        synchronized (this) {
7407            mProcessObservers.unregister(observer);
7408        }
7409    }
7410
7411    public void setImmersive(IBinder token, boolean immersive) {
7412        synchronized(this) {
7413            ActivityRecord r = mMainStack.isInStackLocked(token);
7414            if (r == null) {
7415                throw new IllegalArgumentException();
7416            }
7417            r.immersive = immersive;
7418        }
7419    }
7420
7421    public boolean isImmersive(IBinder token) {
7422        synchronized (this) {
7423            ActivityRecord r = mMainStack.isInStackLocked(token);
7424            if (r == null) {
7425                throw new IllegalArgumentException();
7426            }
7427            return r.immersive;
7428        }
7429    }
7430
7431    public boolean isTopActivityImmersive() {
7432        enforceNotIsolatedCaller("startActivity");
7433        synchronized (this) {
7434            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7435            return (r != null) ? r.immersive : false;
7436        }
7437    }
7438
7439    public final void enterSafeMode() {
7440        synchronized(this) {
7441            // It only makes sense to do this before the system is ready
7442            // and started launching other packages.
7443            if (!mSystemReady) {
7444                try {
7445                    AppGlobals.getPackageManager().enterSafeMode();
7446                } catch (RemoteException e) {
7447                }
7448            }
7449        }
7450    }
7451
7452    public final void showSafeModeOverlay() {
7453        View v = LayoutInflater.from(mContext).inflate(
7454                com.android.internal.R.layout.safe_mode, null);
7455        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7456        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7457        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7458        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7459        lp.gravity = Gravity.BOTTOM | Gravity.START;
7460        lp.format = v.getBackground().getOpacity();
7461        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7462                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7463        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7464        ((WindowManager)mContext.getSystemService(
7465                Context.WINDOW_SERVICE)).addView(v, lp);
7466    }
7467
7468    public void noteWakeupAlarm(IIntentSender sender) {
7469        if (!(sender instanceof PendingIntentRecord)) {
7470            return;
7471        }
7472        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7473        synchronized (stats) {
7474            if (mBatteryStatsService.isOnBattery()) {
7475                mBatteryStatsService.enforceCallingPermission();
7476                PendingIntentRecord rec = (PendingIntentRecord)sender;
7477                int MY_UID = Binder.getCallingUid();
7478                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7479                BatteryStatsImpl.Uid.Pkg pkg =
7480                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7481                pkg.incWakeupsLocked();
7482            }
7483        }
7484    }
7485
7486    public boolean killPids(int[] pids, String pReason, boolean secure) {
7487        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7488            throw new SecurityException("killPids only available to the system");
7489        }
7490        String reason = (pReason == null) ? "Unknown" : pReason;
7491        // XXX Note: don't acquire main activity lock here, because the window
7492        // manager calls in with its locks held.
7493
7494        boolean killed = false;
7495        synchronized (mPidsSelfLocked) {
7496            int[] types = new int[pids.length];
7497            int worstType = 0;
7498            for (int i=0; i<pids.length; i++) {
7499                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7500                if (proc != null) {
7501                    int type = proc.setAdj;
7502                    types[i] = type;
7503                    if (type > worstType) {
7504                        worstType = type;
7505                    }
7506                }
7507            }
7508
7509            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7510            // then constrain it so we will kill all hidden procs.
7511            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7512                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7513                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7514            }
7515
7516            // If this is not a secure call, don't let it kill processes that
7517            // are important.
7518            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7519                worstType = ProcessList.SERVICE_ADJ;
7520            }
7521
7522            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7523            for (int i=0; i<pids.length; i++) {
7524                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7525                if (proc == null) {
7526                    continue;
7527                }
7528                int adj = proc.setAdj;
7529                if (adj >= worstType && !proc.killedBackground) {
7530                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7531                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7532                            proc.processName, adj, reason);
7533                    killed = true;
7534                    proc.killedBackground = true;
7535                    Process.killProcessQuiet(pids[i]);
7536                }
7537            }
7538        }
7539        return killed;
7540    }
7541
7542    @Override
7543    public boolean killProcessesBelowForeground(String reason) {
7544        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7545            throw new SecurityException("killProcessesBelowForeground() only available to system");
7546        }
7547
7548        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7549    }
7550
7551    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7552        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7553            throw new SecurityException("killProcessesBelowAdj() only available to system");
7554        }
7555
7556        boolean killed = false;
7557        synchronized (mPidsSelfLocked) {
7558            final int size = mPidsSelfLocked.size();
7559            for (int i = 0; i < size; i++) {
7560                final int pid = mPidsSelfLocked.keyAt(i);
7561                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7562                if (proc == null) continue;
7563
7564                final int adj = proc.setAdj;
7565                if (adj > belowAdj && !proc.killedBackground) {
7566                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7567                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7568                            proc.pid, proc.processName, adj, reason);
7569                    killed = true;
7570                    proc.killedBackground = true;
7571                    Process.killProcessQuiet(pid);
7572                }
7573            }
7574        }
7575        return killed;
7576    }
7577
7578    public final void startRunning(String pkg, String cls, String action,
7579            String data) {
7580        synchronized(this) {
7581            if (mStartRunning) {
7582                return;
7583            }
7584            mStartRunning = true;
7585            mTopComponent = pkg != null && cls != null
7586                    ? new ComponentName(pkg, cls) : null;
7587            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7588            mTopData = data;
7589            if (!mSystemReady) {
7590                return;
7591            }
7592        }
7593
7594        systemReady(null);
7595    }
7596
7597    private void retrieveSettings() {
7598        final ContentResolver resolver = mContext.getContentResolver();
7599        String debugApp = Settings.Global.getString(
7600            resolver, Settings.Global.DEBUG_APP);
7601        boolean waitForDebugger = Settings.Global.getInt(
7602            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7603        boolean alwaysFinishActivities = Settings.Global.getInt(
7604            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7605
7606        Configuration configuration = new Configuration();
7607        Settings.System.getConfiguration(resolver, configuration);
7608
7609        synchronized (this) {
7610            mDebugApp = mOrigDebugApp = debugApp;
7611            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7612            mAlwaysFinishActivities = alwaysFinishActivities;
7613            // This happens before any activities are started, so we can
7614            // change mConfiguration in-place.
7615            updateConfigurationLocked(configuration, null, false, true);
7616            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7617        }
7618    }
7619
7620    public boolean testIsSystemReady() {
7621        // no need to synchronize(this) just to read & return the value
7622        return mSystemReady;
7623    }
7624
7625    private static File getCalledPreBootReceiversFile() {
7626        File dataDir = Environment.getDataDirectory();
7627        File systemDir = new File(dataDir, "system");
7628        File fname = new File(systemDir, "called_pre_boots.dat");
7629        return fname;
7630    }
7631
7632    static final int LAST_DONE_VERSION = 10000;
7633
7634    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7635        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7636        File file = getCalledPreBootReceiversFile();
7637        FileInputStream fis = null;
7638        try {
7639            fis = new FileInputStream(file);
7640            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7641            int fvers = dis.readInt();
7642            if (fvers == LAST_DONE_VERSION) {
7643                String vers = dis.readUTF();
7644                String codename = dis.readUTF();
7645                String build = dis.readUTF();
7646                if (android.os.Build.VERSION.RELEASE.equals(vers)
7647                        && android.os.Build.VERSION.CODENAME.equals(codename)
7648                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7649                    int num = dis.readInt();
7650                    while (num > 0) {
7651                        num--;
7652                        String pkg = dis.readUTF();
7653                        String cls = dis.readUTF();
7654                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7655                    }
7656                }
7657            }
7658        } catch (FileNotFoundException e) {
7659        } catch (IOException e) {
7660            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7661        } finally {
7662            if (fis != null) {
7663                try {
7664                    fis.close();
7665                } catch (IOException e) {
7666                }
7667            }
7668        }
7669        return lastDoneReceivers;
7670    }
7671
7672    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7673        File file = getCalledPreBootReceiversFile();
7674        FileOutputStream fos = null;
7675        DataOutputStream dos = null;
7676        try {
7677            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7678            fos = new FileOutputStream(file);
7679            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7680            dos.writeInt(LAST_DONE_VERSION);
7681            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7682            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7683            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7684            dos.writeInt(list.size());
7685            for (int i=0; i<list.size(); i++) {
7686                dos.writeUTF(list.get(i).getPackageName());
7687                dos.writeUTF(list.get(i).getClassName());
7688            }
7689        } catch (IOException e) {
7690            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7691            file.delete();
7692        } finally {
7693            FileUtils.sync(fos);
7694            if (dos != null) {
7695                try {
7696                    dos.close();
7697                } catch (IOException e) {
7698                    // TODO Auto-generated catch block
7699                    e.printStackTrace();
7700                }
7701            }
7702        }
7703    }
7704
7705    public void systemReady(final Runnable goingCallback) {
7706        synchronized(this) {
7707            if (mSystemReady) {
7708                if (goingCallback != null) goingCallback.run();
7709                return;
7710            }
7711
7712            // Check to see if there are any update receivers to run.
7713            if (!mDidUpdate) {
7714                if (mWaitingUpdate) {
7715                    return;
7716                }
7717                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7718                List<ResolveInfo> ris = null;
7719                try {
7720                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7721                            intent, null, 0, 0);
7722                } catch (RemoteException e) {
7723                }
7724                if (ris != null) {
7725                    for (int i=ris.size()-1; i>=0; i--) {
7726                        if ((ris.get(i).activityInfo.applicationInfo.flags
7727                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7728                            ris.remove(i);
7729                        }
7730                    }
7731                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7732
7733                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7734
7735                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7736                    for (int i=0; i<ris.size(); i++) {
7737                        ActivityInfo ai = ris.get(i).activityInfo;
7738                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7739                        if (lastDoneReceivers.contains(comp)) {
7740                            ris.remove(i);
7741                            i--;
7742                        }
7743                    }
7744
7745                    final int[] users = getUsersLocked();
7746                    for (int i=0; i<ris.size(); i++) {
7747                        ActivityInfo ai = ris.get(i).activityInfo;
7748                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7749                        doneReceivers.add(comp);
7750                        intent.setComponent(comp);
7751                        for (int j=0; j<users.length; j++) {
7752                            IIntentReceiver finisher = null;
7753                            if (i == ris.size()-1 && j == users.length-1) {
7754                                finisher = new IIntentReceiver.Stub() {
7755                                    public void performReceive(Intent intent, int resultCode,
7756                                            String data, Bundle extras, boolean ordered,
7757                                            boolean sticky, int sendingUser) {
7758                                        // The raw IIntentReceiver interface is called
7759                                        // with the AM lock held, so redispatch to
7760                                        // execute our code without the lock.
7761                                        mHandler.post(new Runnable() {
7762                                            public void run() {
7763                                                synchronized (ActivityManagerService.this) {
7764                                                    mDidUpdate = true;
7765                                                }
7766                                                writeLastDonePreBootReceivers(doneReceivers);
7767                                                showBootMessage(mContext.getText(
7768                                                        R.string.android_upgrading_complete),
7769                                                        false);
7770                                                systemReady(goingCallback);
7771                                            }
7772                                        });
7773                                    }
7774                                };
7775                            }
7776                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7777                                    + " for user " + users[j]);
7778                            broadcastIntentLocked(null, null, intent, null, finisher,
7779                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7780                                    users[j]);
7781                            if (finisher != null) {
7782                                mWaitingUpdate = true;
7783                            }
7784                        }
7785                    }
7786                }
7787                if (mWaitingUpdate) {
7788                    return;
7789                }
7790                mDidUpdate = true;
7791            }
7792
7793            mSystemReady = true;
7794            if (!mStartRunning) {
7795                return;
7796            }
7797        }
7798
7799        ArrayList<ProcessRecord> procsToKill = null;
7800        synchronized(mPidsSelfLocked) {
7801            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7802                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7803                if (!isAllowedWhileBooting(proc.info)){
7804                    if (procsToKill == null) {
7805                        procsToKill = new ArrayList<ProcessRecord>();
7806                    }
7807                    procsToKill.add(proc);
7808                }
7809            }
7810        }
7811
7812        synchronized(this) {
7813            if (procsToKill != null) {
7814                for (int i=procsToKill.size()-1; i>=0; i--) {
7815                    ProcessRecord proc = procsToKill.get(i);
7816                    Slog.i(TAG, "Removing system update proc: " + proc);
7817                    removeProcessLocked(proc, true, false, "system update done");
7818                }
7819            }
7820
7821            // Now that we have cleaned up any update processes, we
7822            // are ready to start launching real processes and know that
7823            // we won't trample on them any more.
7824            mProcessesReady = true;
7825        }
7826
7827        Slog.i(TAG, "System now ready");
7828        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7829            SystemClock.uptimeMillis());
7830
7831        synchronized(this) {
7832            // Make sure we have no pre-ready processes sitting around.
7833
7834            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7835                ResolveInfo ri = mContext.getPackageManager()
7836                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7837                                STOCK_PM_FLAGS);
7838                CharSequence errorMsg = null;
7839                if (ri != null) {
7840                    ActivityInfo ai = ri.activityInfo;
7841                    ApplicationInfo app = ai.applicationInfo;
7842                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7843                        mTopAction = Intent.ACTION_FACTORY_TEST;
7844                        mTopData = null;
7845                        mTopComponent = new ComponentName(app.packageName,
7846                                ai.name);
7847                    } else {
7848                        errorMsg = mContext.getResources().getText(
7849                                com.android.internal.R.string.factorytest_not_system);
7850                    }
7851                } else {
7852                    errorMsg = mContext.getResources().getText(
7853                            com.android.internal.R.string.factorytest_no_action);
7854                }
7855                if (errorMsg != null) {
7856                    mTopAction = null;
7857                    mTopData = null;
7858                    mTopComponent = null;
7859                    Message msg = Message.obtain();
7860                    msg.what = SHOW_FACTORY_ERROR_MSG;
7861                    msg.getData().putCharSequence("msg", errorMsg);
7862                    mHandler.sendMessage(msg);
7863                }
7864            }
7865        }
7866
7867        retrieveSettings();
7868
7869        if (goingCallback != null) goingCallback.run();
7870
7871        synchronized (this) {
7872            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7873                try {
7874                    List apps = AppGlobals.getPackageManager().
7875                        getPersistentApplications(STOCK_PM_FLAGS);
7876                    if (apps != null) {
7877                        int N = apps.size();
7878                        int i;
7879                        for (i=0; i<N; i++) {
7880                            ApplicationInfo info
7881                                = (ApplicationInfo)apps.get(i);
7882                            if (info != null &&
7883                                    !info.packageName.equals("android")) {
7884                                addAppLocked(info, false);
7885                            }
7886                        }
7887                    }
7888                } catch (RemoteException ex) {
7889                    // pm is in same process, this will never happen.
7890                }
7891            }
7892
7893            // Start up initial activity.
7894            mBooting = true;
7895
7896            try {
7897                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7898                    Message msg = Message.obtain();
7899                    msg.what = SHOW_UID_ERROR_MSG;
7900                    mHandler.sendMessage(msg);
7901                }
7902            } catch (RemoteException e) {
7903            }
7904
7905            long ident = Binder.clearCallingIdentity();
7906            try {
7907                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7908                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7909                        | Intent.FLAG_RECEIVER_FOREGROUND);
7910                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7911                broadcastIntentLocked(null, null, intent,
7912                        null, null, 0, null, null, null,
7913                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7914                intent = new Intent(Intent.ACTION_USER_STARTING);
7915                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7916                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7917                broadcastIntentLocked(null, null, intent,
7918                        null, new IIntentReceiver.Stub() {
7919                            @Override
7920                            public void performReceive(Intent intent, int resultCode, String data,
7921                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7922                                    throws RemoteException {
7923                            }
7924                        }, 0, null, null,
7925                        android.Manifest.permission.INTERACT_ACROSS_USERS,
7926                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
7927            } finally {
7928                Binder.restoreCallingIdentity(ident);
7929            }
7930            mMainStack.resumeTopActivityLocked(null);
7931            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7932        }
7933    }
7934
7935    private boolean makeAppCrashingLocked(ProcessRecord app,
7936            String shortMsg, String longMsg, String stackTrace) {
7937        app.crashing = true;
7938        app.crashingReport = generateProcessError(app,
7939                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7940        startAppProblemLocked(app);
7941        app.stopFreezingAllLocked();
7942        return handleAppCrashLocked(app);
7943    }
7944
7945    private void makeAppNotRespondingLocked(ProcessRecord app,
7946            String activity, String shortMsg, String longMsg) {
7947        app.notResponding = true;
7948        app.notRespondingReport = generateProcessError(app,
7949                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7950                activity, shortMsg, longMsg, null);
7951        startAppProblemLocked(app);
7952        app.stopFreezingAllLocked();
7953    }
7954
7955    /**
7956     * Generate a process error record, suitable for attachment to a ProcessRecord.
7957     *
7958     * @param app The ProcessRecord in which the error occurred.
7959     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7960     *                      ActivityManager.AppErrorStateInfo
7961     * @param activity The activity associated with the crash, if known.
7962     * @param shortMsg Short message describing the crash.
7963     * @param longMsg Long message describing the crash.
7964     * @param stackTrace Full crash stack trace, may be null.
7965     *
7966     * @return Returns a fully-formed AppErrorStateInfo record.
7967     */
7968    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7969            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7970        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7971
7972        report.condition = condition;
7973        report.processName = app.processName;
7974        report.pid = app.pid;
7975        report.uid = app.info.uid;
7976        report.tag = activity;
7977        report.shortMsg = shortMsg;
7978        report.longMsg = longMsg;
7979        report.stackTrace = stackTrace;
7980
7981        return report;
7982    }
7983
7984    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7985        synchronized (this) {
7986            app.crashing = false;
7987            app.crashingReport = null;
7988            app.notResponding = false;
7989            app.notRespondingReport = null;
7990            if (app.anrDialog == fromDialog) {
7991                app.anrDialog = null;
7992            }
7993            if (app.waitDialog == fromDialog) {
7994                app.waitDialog = null;
7995            }
7996            if (app.pid > 0 && app.pid != MY_PID) {
7997                handleAppCrashLocked(app);
7998                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7999                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8000                        app.processName, app.setAdj, "user's request after error");
8001                Process.killProcessQuiet(app.pid);
8002            }
8003        }
8004    }
8005
8006    private boolean handleAppCrashLocked(ProcessRecord app) {
8007        if (mHeadless) {
8008            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8009            return false;
8010        }
8011        long now = SystemClock.uptimeMillis();
8012
8013        Long crashTime;
8014        if (!app.isolated) {
8015            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8016        } else {
8017            crashTime = null;
8018        }
8019        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8020            // This process loses!
8021            Slog.w(TAG, "Process " + app.info.processName
8022                    + " has crashed too many times: killing!");
8023            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8024                    app.userId, app.info.processName, app.uid);
8025            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8026                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8027                if (r.app == app) {
8028                    Slog.w(TAG, "  Force finishing activity "
8029                        + r.intent.getComponent().flattenToShortString());
8030                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8031                            null, "crashed", false);
8032                }
8033            }
8034            if (!app.persistent) {
8035                // We don't want to start this process again until the user
8036                // explicitly does so...  but for persistent process, we really
8037                // need to keep it running.  If a persistent process is actually
8038                // repeatedly crashing, then badness for everyone.
8039                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8040                        app.info.processName);
8041                if (!app.isolated) {
8042                    // XXX We don't have a way to mark isolated processes
8043                    // as bad, since they don't have a peristent identity.
8044                    mBadProcesses.put(app.info.processName, app.uid, now);
8045                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8046                }
8047                app.bad = true;
8048                app.removed = true;
8049                // Don't let services in this process be restarted and potentially
8050                // annoy the user repeatedly.  Unless it is persistent, since those
8051                // processes run critical code.
8052                removeProcessLocked(app, false, false, "crash");
8053                mMainStack.resumeTopActivityLocked(null);
8054                return false;
8055            }
8056            mMainStack.resumeTopActivityLocked(null);
8057        } else {
8058            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8059            if (r != null && r.app == app) {
8060                // If the top running activity is from this crashing
8061                // process, then terminate it to avoid getting in a loop.
8062                Slog.w(TAG, "  Force finishing activity "
8063                        + r.intent.getComponent().flattenToShortString());
8064                int index = mMainStack.indexOfActivityLocked(r);
8065                r.stack.finishActivityLocked(r, index,
8066                        Activity.RESULT_CANCELED, null, "crashed", false);
8067                // Also terminate any activities below it that aren't yet
8068                // stopped, to avoid a situation where one will get
8069                // re-start our crashing activity once it gets resumed again.
8070                index--;
8071                if (index >= 0) {
8072                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8073                    if (r.state == ActivityState.RESUMED
8074                            || r.state == ActivityState.PAUSING
8075                            || r.state == ActivityState.PAUSED) {
8076                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8077                            Slog.w(TAG, "  Force finishing activity "
8078                                    + r.intent.getComponent().flattenToShortString());
8079                            r.stack.finishActivityLocked(r, index,
8080                                    Activity.RESULT_CANCELED, null, "crashed", false);
8081                        }
8082                    }
8083                }
8084            }
8085        }
8086
8087        // Bump up the crash count of any services currently running in the proc.
8088        if (app.services.size() != 0) {
8089            // Any services running in the application need to be placed
8090            // back in the pending list.
8091            Iterator<ServiceRecord> it = app.services.iterator();
8092            while (it.hasNext()) {
8093                ServiceRecord sr = it.next();
8094                sr.crashCount++;
8095            }
8096        }
8097
8098        // If the crashing process is what we consider to be the "home process" and it has been
8099        // replaced by a third-party app, clear the package preferred activities from packages
8100        // with a home activity running in the process to prevent a repeatedly crashing app
8101        // from blocking the user to manually clear the list.
8102        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8103                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8104            Iterator it = mHomeProcess.activities.iterator();
8105            while (it.hasNext()) {
8106                ActivityRecord r = (ActivityRecord)it.next();
8107                if (r.isHomeActivity) {
8108                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8109                    try {
8110                        ActivityThread.getPackageManager()
8111                                .clearPackagePreferredActivities(r.packageName);
8112                    } catch (RemoteException c) {
8113                        // pm is in same process, this will never happen.
8114                    }
8115                }
8116            }
8117        }
8118
8119        if (!app.isolated) {
8120            // XXX Can't keep track of crash times for isolated processes,
8121            // because they don't have a perisistent identity.
8122            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8123        }
8124
8125        return true;
8126    }
8127
8128    void startAppProblemLocked(ProcessRecord app) {
8129        if (app.userId == mCurrentUserId) {
8130            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8131                    mContext, app.info.packageName, app.info.flags);
8132        } else {
8133            // If this app is not running under the current user, then we
8134            // can't give it a report button because that would require
8135            // launching the report UI under a different user.
8136            app.errorReportReceiver = null;
8137        }
8138        skipCurrentReceiverLocked(app);
8139    }
8140
8141    void skipCurrentReceiverLocked(ProcessRecord app) {
8142        for (BroadcastQueue queue : mBroadcastQueues) {
8143            queue.skipCurrentReceiverLocked(app);
8144        }
8145    }
8146
8147    /**
8148     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8149     * The application process will exit immediately after this call returns.
8150     * @param app object of the crashing app, null for the system server
8151     * @param crashInfo describing the exception
8152     */
8153    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8154        ProcessRecord r = findAppProcess(app, "Crash");
8155        final String processName = app == null ? "system_server"
8156                : (r == null ? "unknown" : r.processName);
8157
8158        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8159                UserHandle.getUserId(Binder.getCallingUid()), processName,
8160                r == null ? -1 : r.info.flags,
8161                crashInfo.exceptionClassName,
8162                crashInfo.exceptionMessage,
8163                crashInfo.throwFileName,
8164                crashInfo.throwLineNumber);
8165
8166        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8167
8168        crashApplication(r, crashInfo);
8169    }
8170
8171    public void handleApplicationStrictModeViolation(
8172            IBinder app,
8173            int violationMask,
8174            StrictMode.ViolationInfo info) {
8175        ProcessRecord r = findAppProcess(app, "StrictMode");
8176        if (r == null) {
8177            return;
8178        }
8179
8180        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8181            Integer stackFingerprint = info.hashCode();
8182            boolean logIt = true;
8183            synchronized (mAlreadyLoggedViolatedStacks) {
8184                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8185                    logIt = false;
8186                    // TODO: sub-sample into EventLog for these, with
8187                    // the info.durationMillis?  Then we'd get
8188                    // the relative pain numbers, without logging all
8189                    // the stack traces repeatedly.  We'd want to do
8190                    // likewise in the client code, which also does
8191                    // dup suppression, before the Binder call.
8192                } else {
8193                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8194                        mAlreadyLoggedViolatedStacks.clear();
8195                    }
8196                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8197                }
8198            }
8199            if (logIt) {
8200                logStrictModeViolationToDropBox(r, info);
8201            }
8202        }
8203
8204        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8205            AppErrorResult result = new AppErrorResult();
8206            synchronized (this) {
8207                final long origId = Binder.clearCallingIdentity();
8208
8209                Message msg = Message.obtain();
8210                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8211                HashMap<String, Object> data = new HashMap<String, Object>();
8212                data.put("result", result);
8213                data.put("app", r);
8214                data.put("violationMask", violationMask);
8215                data.put("info", info);
8216                msg.obj = data;
8217                mHandler.sendMessage(msg);
8218
8219                Binder.restoreCallingIdentity(origId);
8220            }
8221            int res = result.get();
8222            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8223        }
8224    }
8225
8226    // Depending on the policy in effect, there could be a bunch of
8227    // these in quick succession so we try to batch these together to
8228    // minimize disk writes, number of dropbox entries, and maximize
8229    // compression, by having more fewer, larger records.
8230    private void logStrictModeViolationToDropBox(
8231            ProcessRecord process,
8232            StrictMode.ViolationInfo info) {
8233        if (info == null) {
8234            return;
8235        }
8236        final boolean isSystemApp = process == null ||
8237                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8238                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8239        final String processName = process == null ? "unknown" : process.processName;
8240        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8241        final DropBoxManager dbox = (DropBoxManager)
8242                mContext.getSystemService(Context.DROPBOX_SERVICE);
8243
8244        // Exit early if the dropbox isn't configured to accept this report type.
8245        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8246
8247        boolean bufferWasEmpty;
8248        boolean needsFlush;
8249        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8250        synchronized (sb) {
8251            bufferWasEmpty = sb.length() == 0;
8252            appendDropBoxProcessHeaders(process, processName, sb);
8253            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8254            sb.append("System-App: ").append(isSystemApp).append("\n");
8255            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8256            if (info.violationNumThisLoop != 0) {
8257                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8258            }
8259            if (info.numAnimationsRunning != 0) {
8260                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8261            }
8262            if (info.broadcastIntentAction != null) {
8263                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8264            }
8265            if (info.durationMillis != -1) {
8266                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8267            }
8268            if (info.numInstances != -1) {
8269                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8270            }
8271            if (info.tags != null) {
8272                for (String tag : info.tags) {
8273                    sb.append("Span-Tag: ").append(tag).append("\n");
8274                }
8275            }
8276            sb.append("\n");
8277            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8278                sb.append(info.crashInfo.stackTrace);
8279            }
8280            sb.append("\n");
8281
8282            // Only buffer up to ~64k.  Various logging bits truncate
8283            // things at 128k.
8284            needsFlush = (sb.length() > 64 * 1024);
8285        }
8286
8287        // Flush immediately if the buffer's grown too large, or this
8288        // is a non-system app.  Non-system apps are isolated with a
8289        // different tag & policy and not batched.
8290        //
8291        // Batching is useful during internal testing with
8292        // StrictMode settings turned up high.  Without batching,
8293        // thousands of separate files could be created on boot.
8294        if (!isSystemApp || needsFlush) {
8295            new Thread("Error dump: " + dropboxTag) {
8296                @Override
8297                public void run() {
8298                    String report;
8299                    synchronized (sb) {
8300                        report = sb.toString();
8301                        sb.delete(0, sb.length());
8302                        sb.trimToSize();
8303                    }
8304                    if (report.length() != 0) {
8305                        dbox.addText(dropboxTag, report);
8306                    }
8307                }
8308            }.start();
8309            return;
8310        }
8311
8312        // System app batching:
8313        if (!bufferWasEmpty) {
8314            // An existing dropbox-writing thread is outstanding, so
8315            // we don't need to start it up.  The existing thread will
8316            // catch the buffer appends we just did.
8317            return;
8318        }
8319
8320        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8321        // (After this point, we shouldn't access AMS internal data structures.)
8322        new Thread("Error dump: " + dropboxTag) {
8323            @Override
8324            public void run() {
8325                // 5 second sleep to let stacks arrive and be batched together
8326                try {
8327                    Thread.sleep(5000);  // 5 seconds
8328                } catch (InterruptedException e) {}
8329
8330                String errorReport;
8331                synchronized (mStrictModeBuffer) {
8332                    errorReport = mStrictModeBuffer.toString();
8333                    if (errorReport.length() == 0) {
8334                        return;
8335                    }
8336                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8337                    mStrictModeBuffer.trimToSize();
8338                }
8339                dbox.addText(dropboxTag, errorReport);
8340            }
8341        }.start();
8342    }
8343
8344    /**
8345     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8346     * @param app object of the crashing app, null for the system server
8347     * @param tag reported by the caller
8348     * @param crashInfo describing the context of the error
8349     * @return true if the process should exit immediately (WTF is fatal)
8350     */
8351    public boolean handleApplicationWtf(IBinder app, String tag,
8352            ApplicationErrorReport.CrashInfo crashInfo) {
8353        ProcessRecord r = findAppProcess(app, "WTF");
8354        final String processName = app == null ? "system_server"
8355                : (r == null ? "unknown" : r.processName);
8356
8357        EventLog.writeEvent(EventLogTags.AM_WTF,
8358                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8359                processName,
8360                r == null ? -1 : r.info.flags,
8361                tag, crashInfo.exceptionMessage);
8362
8363        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8364
8365        if (r != null && r.pid != Process.myPid() &&
8366                Settings.Global.getInt(mContext.getContentResolver(),
8367                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8368            crashApplication(r, crashInfo);
8369            return true;
8370        } else {
8371            return false;
8372        }
8373    }
8374
8375    /**
8376     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8377     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8378     */
8379    private ProcessRecord findAppProcess(IBinder app, String reason) {
8380        if (app == null) {
8381            return null;
8382        }
8383
8384        synchronized (this) {
8385            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8386                final int NA = apps.size();
8387                for (int ia=0; ia<NA; ia++) {
8388                    ProcessRecord p = apps.valueAt(ia);
8389                    if (p.thread != null && p.thread.asBinder() == app) {
8390                        return p;
8391                    }
8392                }
8393            }
8394
8395            Slog.w(TAG, "Can't find mystery application for " + reason
8396                    + " from pid=" + Binder.getCallingPid()
8397                    + " uid=" + Binder.getCallingUid() + ": " + app);
8398            return null;
8399        }
8400    }
8401
8402    /**
8403     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8404     * to append various headers to the dropbox log text.
8405     */
8406    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8407            StringBuilder sb) {
8408        // Watchdog thread ends up invoking this function (with
8409        // a null ProcessRecord) to add the stack file to dropbox.
8410        // Do not acquire a lock on this (am) in such cases, as it
8411        // could cause a potential deadlock, if and when watchdog
8412        // is invoked due to unavailability of lock on am and it
8413        // would prevent watchdog from killing system_server.
8414        if (process == null) {
8415            sb.append("Process: ").append(processName).append("\n");
8416            return;
8417        }
8418        // Note: ProcessRecord 'process' is guarded by the service
8419        // instance.  (notably process.pkgList, which could otherwise change
8420        // concurrently during execution of this method)
8421        synchronized (this) {
8422            sb.append("Process: ").append(processName).append("\n");
8423            int flags = process.info.flags;
8424            IPackageManager pm = AppGlobals.getPackageManager();
8425            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8426            for (String pkg : process.pkgList) {
8427                sb.append("Package: ").append(pkg);
8428                try {
8429                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8430                    if (pi != null) {
8431                        sb.append(" v").append(pi.versionCode);
8432                        if (pi.versionName != null) {
8433                            sb.append(" (").append(pi.versionName).append(")");
8434                        }
8435                    }
8436                } catch (RemoteException e) {
8437                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8438                }
8439                sb.append("\n");
8440            }
8441        }
8442    }
8443
8444    private static String processClass(ProcessRecord process) {
8445        if (process == null || process.pid == MY_PID) {
8446            return "system_server";
8447        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8448            return "system_app";
8449        } else {
8450            return "data_app";
8451        }
8452    }
8453
8454    /**
8455     * Write a description of an error (crash, WTF, ANR) to the drop box.
8456     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8457     * @param process which caused the error, null means the system server
8458     * @param activity which triggered the error, null if unknown
8459     * @param parent activity related to the error, null if unknown
8460     * @param subject line related to the error, null if absent
8461     * @param report in long form describing the error, null if absent
8462     * @param logFile to include in the report, null if none
8463     * @param crashInfo giving an application stack trace, null if absent
8464     */
8465    public void addErrorToDropBox(String eventType,
8466            ProcessRecord process, String processName, ActivityRecord activity,
8467            ActivityRecord parent, String subject,
8468            final String report, final File logFile,
8469            final ApplicationErrorReport.CrashInfo crashInfo) {
8470        // NOTE -- this must never acquire the ActivityManagerService lock,
8471        // otherwise the watchdog may be prevented from resetting the system.
8472
8473        final String dropboxTag = processClass(process) + "_" + eventType;
8474        final DropBoxManager dbox = (DropBoxManager)
8475                mContext.getSystemService(Context.DROPBOX_SERVICE);
8476
8477        // Exit early if the dropbox isn't configured to accept this report type.
8478        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8479
8480        final StringBuilder sb = new StringBuilder(1024);
8481        appendDropBoxProcessHeaders(process, processName, sb);
8482        if (activity != null) {
8483            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8484        }
8485        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8486            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8487        }
8488        if (parent != null && parent != activity) {
8489            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8490        }
8491        if (subject != null) {
8492            sb.append("Subject: ").append(subject).append("\n");
8493        }
8494        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8495        if (Debug.isDebuggerConnected()) {
8496            sb.append("Debugger: Connected\n");
8497        }
8498        sb.append("\n");
8499
8500        // Do the rest in a worker thread to avoid blocking the caller on I/O
8501        // (After this point, we shouldn't access AMS internal data structures.)
8502        Thread worker = new Thread("Error dump: " + dropboxTag) {
8503            @Override
8504            public void run() {
8505                if (report != null) {
8506                    sb.append(report);
8507                }
8508                if (logFile != null) {
8509                    try {
8510                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8511                    } catch (IOException e) {
8512                        Slog.e(TAG, "Error reading " + logFile, e);
8513                    }
8514                }
8515                if (crashInfo != null && crashInfo.stackTrace != null) {
8516                    sb.append(crashInfo.stackTrace);
8517                }
8518
8519                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8520                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8521                if (lines > 0) {
8522                    sb.append("\n");
8523
8524                    // Merge several logcat streams, and take the last N lines
8525                    InputStreamReader input = null;
8526                    try {
8527                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8528                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8529                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8530
8531                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8532                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8533                        input = new InputStreamReader(logcat.getInputStream());
8534
8535                        int num;
8536                        char[] buf = new char[8192];
8537                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8538                    } catch (IOException e) {
8539                        Slog.e(TAG, "Error running logcat", e);
8540                    } finally {
8541                        if (input != null) try { input.close(); } catch (IOException e) {}
8542                    }
8543                }
8544
8545                dbox.addText(dropboxTag, sb.toString());
8546            }
8547        };
8548
8549        if (process == null) {
8550            // If process is null, we are being called from some internal code
8551            // and may be about to die -- run this synchronously.
8552            worker.run();
8553        } else {
8554            worker.start();
8555        }
8556    }
8557
8558    /**
8559     * Bring up the "unexpected error" dialog box for a crashing app.
8560     * Deal with edge cases (intercepts from instrumented applications,
8561     * ActivityController, error intent receivers, that sort of thing).
8562     * @param r the application crashing
8563     * @param crashInfo describing the failure
8564     */
8565    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8566        long timeMillis = System.currentTimeMillis();
8567        String shortMsg = crashInfo.exceptionClassName;
8568        String longMsg = crashInfo.exceptionMessage;
8569        String stackTrace = crashInfo.stackTrace;
8570        if (shortMsg != null && longMsg != null) {
8571            longMsg = shortMsg + ": " + longMsg;
8572        } else if (shortMsg != null) {
8573            longMsg = shortMsg;
8574        }
8575
8576        AppErrorResult result = new AppErrorResult();
8577        synchronized (this) {
8578            if (mController != null) {
8579                try {
8580                    String name = r != null ? r.processName : null;
8581                    int pid = r != null ? r.pid : Binder.getCallingPid();
8582                    if (!mController.appCrashed(name, pid,
8583                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8584                        Slog.w(TAG, "Force-killing crashed app " + name
8585                                + " at watcher's request");
8586                        Process.killProcess(pid);
8587                        return;
8588                    }
8589                } catch (RemoteException e) {
8590                    mController = null;
8591                }
8592            }
8593
8594            final long origId = Binder.clearCallingIdentity();
8595
8596            // If this process is running instrumentation, finish it.
8597            if (r != null && r.instrumentationClass != null) {
8598                Slog.w(TAG, "Error in app " + r.processName
8599                      + " running instrumentation " + r.instrumentationClass + ":");
8600                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8601                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8602                Bundle info = new Bundle();
8603                info.putString("shortMsg", shortMsg);
8604                info.putString("longMsg", longMsg);
8605                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8606                Binder.restoreCallingIdentity(origId);
8607                return;
8608            }
8609
8610            // If we can't identify the process or it's already exceeded its crash quota,
8611            // quit right away without showing a crash dialog.
8612            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8613                Binder.restoreCallingIdentity(origId);
8614                return;
8615            }
8616
8617            Message msg = Message.obtain();
8618            msg.what = SHOW_ERROR_MSG;
8619            HashMap data = new HashMap();
8620            data.put("result", result);
8621            data.put("app", r);
8622            msg.obj = data;
8623            mHandler.sendMessage(msg);
8624
8625            Binder.restoreCallingIdentity(origId);
8626        }
8627
8628        int res = result.get();
8629
8630        Intent appErrorIntent = null;
8631        synchronized (this) {
8632            if (r != null && !r.isolated) {
8633                // XXX Can't keep track of crash time for isolated processes,
8634                // since they don't have a persistent identity.
8635                mProcessCrashTimes.put(r.info.processName, r.uid,
8636                        SystemClock.uptimeMillis());
8637            }
8638            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8639                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8640            }
8641        }
8642
8643        if (appErrorIntent != null) {
8644            try {
8645                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8646            } catch (ActivityNotFoundException e) {
8647                Slog.w(TAG, "bug report receiver dissappeared", e);
8648            }
8649        }
8650    }
8651
8652    Intent createAppErrorIntentLocked(ProcessRecord r,
8653            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8654        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8655        if (report == null) {
8656            return null;
8657        }
8658        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8659        result.setComponent(r.errorReportReceiver);
8660        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8661        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8662        return result;
8663    }
8664
8665    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8666            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8667        if (r.errorReportReceiver == null) {
8668            return null;
8669        }
8670
8671        if (!r.crashing && !r.notResponding) {
8672            return null;
8673        }
8674
8675        ApplicationErrorReport report = new ApplicationErrorReport();
8676        report.packageName = r.info.packageName;
8677        report.installerPackageName = r.errorReportReceiver.getPackageName();
8678        report.processName = r.processName;
8679        report.time = timeMillis;
8680        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8681
8682        if (r.crashing) {
8683            report.type = ApplicationErrorReport.TYPE_CRASH;
8684            report.crashInfo = crashInfo;
8685        } else if (r.notResponding) {
8686            report.type = ApplicationErrorReport.TYPE_ANR;
8687            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8688
8689            report.anrInfo.activity = r.notRespondingReport.tag;
8690            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8691            report.anrInfo.info = r.notRespondingReport.longMsg;
8692        }
8693
8694        return report;
8695    }
8696
8697    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8698        enforceNotIsolatedCaller("getProcessesInErrorState");
8699        // assume our apps are happy - lazy create the list
8700        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8701
8702        final boolean allUsers = ActivityManager.checkUidPermission(
8703                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8704                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8705        int userId = UserHandle.getUserId(Binder.getCallingUid());
8706
8707        synchronized (this) {
8708
8709            // iterate across all processes
8710            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8711                ProcessRecord app = mLruProcesses.get(i);
8712                if (!allUsers && app.userId != userId) {
8713                    continue;
8714                }
8715                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8716                    // This one's in trouble, so we'll generate a report for it
8717                    // crashes are higher priority (in case there's a crash *and* an anr)
8718                    ActivityManager.ProcessErrorStateInfo report = null;
8719                    if (app.crashing) {
8720                        report = app.crashingReport;
8721                    } else if (app.notResponding) {
8722                        report = app.notRespondingReport;
8723                    }
8724
8725                    if (report != null) {
8726                        if (errList == null) {
8727                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8728                        }
8729                        errList.add(report);
8730                    } else {
8731                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8732                                " crashing = " + app.crashing +
8733                                " notResponding = " + app.notResponding);
8734                    }
8735                }
8736            }
8737        }
8738
8739        return errList;
8740    }
8741
8742    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8743        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8744            if (currApp != null) {
8745                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8746            }
8747            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8748        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8749            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8750        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8751            if (currApp != null) {
8752                currApp.lru = 0;
8753            }
8754            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8755        } else if (adj >= ProcessList.SERVICE_ADJ) {
8756            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8757        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8758            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8759        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8760            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8761        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8762            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8763        } else {
8764            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8765        }
8766    }
8767
8768    private void fillInProcMemInfo(ProcessRecord app,
8769            ActivityManager.RunningAppProcessInfo outInfo) {
8770        outInfo.pid = app.pid;
8771        outInfo.uid = app.info.uid;
8772        if (mHeavyWeightProcess == app) {
8773            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8774        }
8775        if (app.persistent) {
8776            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8777        }
8778        if (app.hasActivities) {
8779            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8780        }
8781        outInfo.lastTrimLevel = app.trimMemoryLevel;
8782        int adj = app.curAdj;
8783        outInfo.importance = oomAdjToImportance(adj, outInfo);
8784        outInfo.importanceReasonCode = app.adjTypeCode;
8785    }
8786
8787    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8788        enforceNotIsolatedCaller("getRunningAppProcesses");
8789        // Lazy instantiation of list
8790        List<ActivityManager.RunningAppProcessInfo> runList = null;
8791        final boolean allUsers = ActivityManager.checkUidPermission(
8792                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8793                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8794        int userId = UserHandle.getUserId(Binder.getCallingUid());
8795        synchronized (this) {
8796            // Iterate across all processes
8797            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8798                ProcessRecord app = mLruProcesses.get(i);
8799                if (!allUsers && app.userId != userId) {
8800                    continue;
8801                }
8802                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8803                    // Generate process state info for running application
8804                    ActivityManager.RunningAppProcessInfo currApp =
8805                        new ActivityManager.RunningAppProcessInfo(app.processName,
8806                                app.pid, app.getPackageList());
8807                    fillInProcMemInfo(app, currApp);
8808                    if (app.adjSource instanceof ProcessRecord) {
8809                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8810                        currApp.importanceReasonImportance = oomAdjToImportance(
8811                                app.adjSourceOom, null);
8812                    } else if (app.adjSource instanceof ActivityRecord) {
8813                        ActivityRecord r = (ActivityRecord)app.adjSource;
8814                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8815                    }
8816                    if (app.adjTarget instanceof ComponentName) {
8817                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8818                    }
8819                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8820                    //        + " lru=" + currApp.lru);
8821                    if (runList == null) {
8822                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8823                    }
8824                    runList.add(currApp);
8825                }
8826            }
8827        }
8828        return runList;
8829    }
8830
8831    public List<ApplicationInfo> getRunningExternalApplications() {
8832        enforceNotIsolatedCaller("getRunningExternalApplications");
8833        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8834        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8835        if (runningApps != null && runningApps.size() > 0) {
8836            Set<String> extList = new HashSet<String>();
8837            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8838                if (app.pkgList != null) {
8839                    for (String pkg : app.pkgList) {
8840                        extList.add(pkg);
8841                    }
8842                }
8843            }
8844            IPackageManager pm = AppGlobals.getPackageManager();
8845            for (String pkg : extList) {
8846                try {
8847                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8848                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8849                        retList.add(info);
8850                    }
8851                } catch (RemoteException e) {
8852                }
8853            }
8854        }
8855        return retList;
8856    }
8857
8858    @Override
8859    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8860        enforceNotIsolatedCaller("getMyMemoryState");
8861        synchronized (this) {
8862            ProcessRecord proc;
8863            synchronized (mPidsSelfLocked) {
8864                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8865            }
8866            fillInProcMemInfo(proc, outInfo);
8867        }
8868    }
8869
8870    @Override
8871    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8872        if (checkCallingPermission(android.Manifest.permission.DUMP)
8873                != PackageManager.PERMISSION_GRANTED) {
8874            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8875                    + Binder.getCallingPid()
8876                    + ", uid=" + Binder.getCallingUid()
8877                    + " without permission "
8878                    + android.Manifest.permission.DUMP);
8879            return;
8880        }
8881
8882        boolean dumpAll = false;
8883        boolean dumpClient = false;
8884        String dumpPackage = null;
8885
8886        int opti = 0;
8887        while (opti < args.length) {
8888            String opt = args[opti];
8889            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8890                break;
8891            }
8892            opti++;
8893            if ("-a".equals(opt)) {
8894                dumpAll = true;
8895            } else if ("-c".equals(opt)) {
8896                dumpClient = true;
8897            } else if ("-h".equals(opt)) {
8898                pw.println("Activity manager dump options:");
8899                pw.println("  [-a] [-c] [-h] [cmd] ...");
8900                pw.println("  cmd may be one of:");
8901                pw.println("    a[ctivities]: activity stack state");
8902                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
8903                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8904                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8905                pw.println("    o[om]: out of memory management");
8906                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8907                pw.println("    provider [COMP_SPEC]: provider client-side state");
8908                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8909                pw.println("    service [COMP_SPEC]: service client-side state");
8910                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8911                pw.println("    all: dump all activities");
8912                pw.println("    top: dump the top activity");
8913                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8914                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8915                pw.println("    a partial substring in a component name, a");
8916                pw.println("    hex object identifier.");
8917                pw.println("  -a: include all available server state.");
8918                pw.println("  -c: include client state.");
8919                return;
8920            } else {
8921                pw.println("Unknown argument: " + opt + "; use -h for help");
8922            }
8923        }
8924
8925        long origId = Binder.clearCallingIdentity();
8926        boolean more = false;
8927        // Is the caller requesting to dump a particular piece of data?
8928        if (opti < args.length) {
8929            String cmd = args[opti];
8930            opti++;
8931            if ("activities".equals(cmd) || "a".equals(cmd)) {
8932                synchronized (this) {
8933                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8934                }
8935            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8936                String[] newArgs;
8937                String name;
8938                if (opti >= args.length) {
8939                    name = null;
8940                    newArgs = EMPTY_STRING_ARRAY;
8941                } else {
8942                    name = args[opti];
8943                    opti++;
8944                    newArgs = new String[args.length - opti];
8945                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8946                            args.length - opti);
8947                }
8948                synchronized (this) {
8949                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8950                }
8951            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8952                String[] newArgs;
8953                String name;
8954                if (opti >= args.length) {
8955                    name = null;
8956                    newArgs = EMPTY_STRING_ARRAY;
8957                } else {
8958                    name = args[opti];
8959                    opti++;
8960                    newArgs = new String[args.length - opti];
8961                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8962                            args.length - opti);
8963                }
8964                synchronized (this) {
8965                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8966                }
8967            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8968                String[] newArgs;
8969                String name;
8970                if (opti >= args.length) {
8971                    name = null;
8972                    newArgs = EMPTY_STRING_ARRAY;
8973                } else {
8974                    name = args[opti];
8975                    opti++;
8976                    newArgs = new String[args.length - opti];
8977                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8978                            args.length - opti);
8979                }
8980                synchronized (this) {
8981                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8982                }
8983            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8984                synchronized (this) {
8985                    dumpOomLocked(fd, pw, args, opti, true);
8986                }
8987            } else if ("provider".equals(cmd)) {
8988                String[] newArgs;
8989                String name;
8990                if (opti >= args.length) {
8991                    name = null;
8992                    newArgs = EMPTY_STRING_ARRAY;
8993                } else {
8994                    name = args[opti];
8995                    opti++;
8996                    newArgs = new String[args.length - opti];
8997                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8998                }
8999                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9000                    pw.println("No providers match: " + name);
9001                    pw.println("Use -h for help.");
9002                }
9003            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9004                synchronized (this) {
9005                    dumpProvidersLocked(fd, pw, args, opti, true, null);
9006                }
9007            } else if ("service".equals(cmd)) {
9008                String[] newArgs;
9009                String name;
9010                if (opti >= args.length) {
9011                    name = null;
9012                    newArgs = EMPTY_STRING_ARRAY;
9013                } else {
9014                    name = args[opti];
9015                    opti++;
9016                    newArgs = new String[args.length - opti];
9017                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9018                            args.length - opti);
9019                }
9020                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9021                    pw.println("No services match: " + name);
9022                    pw.println("Use -h for help.");
9023                }
9024            } else if ("package".equals(cmd)) {
9025                String[] newArgs;
9026                if (opti >= args.length) {
9027                    pw.println("package: no package name specified");
9028                    pw.println("Use -h for help.");
9029                } else {
9030                    dumpPackage = args[opti];
9031                    opti++;
9032                    newArgs = new String[args.length - opti];
9033                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9034                            args.length - opti);
9035                    args = newArgs;
9036                    opti = 0;
9037                    more = true;
9038                }
9039            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9040                synchronized (this) {
9041                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9042                }
9043            } else {
9044                // Dumping a single activity?
9045                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9046                    pw.println("Bad activity command, or no activities match: " + cmd);
9047                    pw.println("Use -h for help.");
9048                }
9049            }
9050            if (!more) {
9051                Binder.restoreCallingIdentity(origId);
9052                return;
9053            }
9054        }
9055
9056        // No piece of data specified, dump everything.
9057        synchronized (this) {
9058            boolean needSep;
9059            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9060            if (needSep) {
9061                pw.println(" ");
9062            }
9063            if (dumpAll) {
9064                pw.println("-------------------------------------------------------------------------------");
9065            }
9066            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9067            if (needSep) {
9068                pw.println(" ");
9069            }
9070            if (dumpAll) {
9071                pw.println("-------------------------------------------------------------------------------");
9072            }
9073            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9074            if (needSep) {
9075                pw.println(" ");
9076            }
9077            if (dumpAll) {
9078                pw.println("-------------------------------------------------------------------------------");
9079            }
9080            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9081            if (needSep) {
9082                pw.println(" ");
9083            }
9084            if (dumpAll) {
9085                pw.println("-------------------------------------------------------------------------------");
9086            }
9087            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9088            if (needSep) {
9089                pw.println(" ");
9090            }
9091            if (dumpAll) {
9092                pw.println("-------------------------------------------------------------------------------");
9093            }
9094            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9095        }
9096        Binder.restoreCallingIdentity(origId);
9097    }
9098
9099    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9100            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9101        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9102        pw.println("  Main stack:");
9103        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9104                dumpPackage);
9105        pw.println(" ");
9106        pw.println("  Running activities (most recent first):");
9107        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9108                dumpPackage);
9109        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9110            pw.println(" ");
9111            pw.println("  Activities waiting for another to become visible:");
9112            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9113                    !dumpAll, false, dumpPackage);
9114        }
9115        if (mMainStack.mStoppingActivities.size() > 0) {
9116            pw.println(" ");
9117            pw.println("  Activities waiting to stop:");
9118            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9119                    !dumpAll, false, dumpPackage);
9120        }
9121        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9122            pw.println(" ");
9123            pw.println("  Activities waiting to sleep:");
9124            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9125                    !dumpAll, false, dumpPackage);
9126        }
9127        if (mMainStack.mFinishingActivities.size() > 0) {
9128            pw.println(" ");
9129            pw.println("  Activities waiting to finish:");
9130            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9131                    !dumpAll, false, dumpPackage);
9132        }
9133
9134        pw.println(" ");
9135        if (mMainStack.mPausingActivity != null) {
9136            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9137        }
9138        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9139        pw.println("  mFocusedActivity: " + mFocusedActivity);
9140        if (dumpAll) {
9141            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9142            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9143            pw.println("  mDismissKeyguardOnNextActivity: "
9144                    + mMainStack.mDismissKeyguardOnNextActivity);
9145        }
9146
9147        if (mRecentTasks.size() > 0) {
9148            pw.println();
9149            pw.println("  Recent tasks:");
9150
9151            final int N = mRecentTasks.size();
9152            for (int i=0; i<N; i++) {
9153                TaskRecord tr = mRecentTasks.get(i);
9154                if (dumpPackage != null) {
9155                    if (tr.realActivity == null ||
9156                            !dumpPackage.equals(tr.realActivity)) {
9157                        continue;
9158                    }
9159                }
9160                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9161                        pw.println(tr);
9162                if (dumpAll) {
9163                    mRecentTasks.get(i).dump(pw, "    ");
9164                }
9165            }
9166        }
9167
9168        if (dumpAll) {
9169            pw.println(" ");
9170            pw.println("  mCurTask: " + mCurTask);
9171        }
9172
9173        return true;
9174    }
9175
9176    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9177            int opti, boolean dumpAll, String dumpPackage) {
9178        boolean needSep = false;
9179        int numPers = 0;
9180
9181        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9182
9183        if (dumpAll) {
9184            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9185                final int NA = procs.size();
9186                for (int ia=0; ia<NA; ia++) {
9187                    ProcessRecord r = procs.valueAt(ia);
9188                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9189                        continue;
9190                    }
9191                    if (!needSep) {
9192                        pw.println("  All known processes:");
9193                        needSep = true;
9194                    }
9195                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9196                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9197                        pw.print(" "); pw.println(r);
9198                    r.dump(pw, "    ");
9199                    if (r.persistent) {
9200                        numPers++;
9201                    }
9202                }
9203            }
9204        }
9205
9206        if (mIsolatedProcesses.size() > 0) {
9207            if (needSep) pw.println(" ");
9208            needSep = true;
9209            pw.println("  Isolated process list (sorted by uid):");
9210            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9211                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9212                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9213                    continue;
9214                }
9215                pw.println(String.format("%sIsolated #%2d: %s",
9216                        "    ", i, r.toString()));
9217            }
9218        }
9219
9220        if (mLruProcesses.size() > 0) {
9221            if (needSep) pw.println(" ");
9222            needSep = true;
9223            pw.println("  Process LRU list (sorted by oom_adj):");
9224            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9225                    "Proc", "PERS", false, dumpPackage);
9226            needSep = true;
9227        }
9228
9229        if (dumpAll) {
9230            synchronized (mPidsSelfLocked) {
9231                boolean printed = false;
9232                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9233                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9234                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9235                        continue;
9236                    }
9237                    if (!printed) {
9238                        if (needSep) pw.println(" ");
9239                        needSep = true;
9240                        pw.println("  PID mappings:");
9241                        printed = true;
9242                    }
9243                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9244                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9245                }
9246            }
9247        }
9248
9249        if (mForegroundProcesses.size() > 0) {
9250            synchronized (mPidsSelfLocked) {
9251                boolean printed = false;
9252                for (int i=0; i<mForegroundProcesses.size(); i++) {
9253                    ProcessRecord r = mPidsSelfLocked.get(
9254                            mForegroundProcesses.valueAt(i).pid);
9255                    if (dumpPackage != null && (r == null
9256                            || !dumpPackage.equals(r.info.packageName))) {
9257                        continue;
9258                    }
9259                    if (!printed) {
9260                        if (needSep) pw.println(" ");
9261                        needSep = true;
9262                        pw.println("  Foreground Processes:");
9263                        printed = true;
9264                    }
9265                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9266                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9267                }
9268            }
9269        }
9270
9271        if (mPersistentStartingProcesses.size() > 0) {
9272            if (needSep) pw.println(" ");
9273            needSep = true;
9274            pw.println("  Persisent processes that are starting:");
9275            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9276                    "Starting Norm", "Restarting PERS", dumpPackage);
9277        }
9278
9279        if (mRemovedProcesses.size() > 0) {
9280            if (needSep) pw.println(" ");
9281            needSep = true;
9282            pw.println("  Processes that are being removed:");
9283            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9284                    "Removed Norm", "Removed PERS", dumpPackage);
9285        }
9286
9287        if (mProcessesOnHold.size() > 0) {
9288            if (needSep) pw.println(" ");
9289            needSep = true;
9290            pw.println("  Processes that are on old until the system is ready:");
9291            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9292                    "OnHold Norm", "OnHold PERS", dumpPackage);
9293        }
9294
9295        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9296
9297        if (mProcessCrashTimes.getMap().size() > 0) {
9298            boolean printed = false;
9299            long now = SystemClock.uptimeMillis();
9300            for (Map.Entry<String, SparseArray<Long>> procs
9301                    : mProcessCrashTimes.getMap().entrySet()) {
9302                String pname = procs.getKey();
9303                SparseArray<Long> uids = procs.getValue();
9304                final int N = uids.size();
9305                for (int i=0; i<N; i++) {
9306                    int puid = uids.keyAt(i);
9307                    ProcessRecord r = mProcessNames.get(pname, puid);
9308                    if (dumpPackage != null && (r == null
9309                            || !dumpPackage.equals(r.info.packageName))) {
9310                        continue;
9311                    }
9312                    if (!printed) {
9313                        if (needSep) pw.println(" ");
9314                        needSep = true;
9315                        pw.println("  Time since processes crashed:");
9316                        printed = true;
9317                    }
9318                    pw.print("    Process "); pw.print(pname);
9319                            pw.print(" uid "); pw.print(puid);
9320                            pw.print(": last crashed ");
9321                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9322                            pw.println(" ago");
9323                }
9324            }
9325        }
9326
9327        if (mBadProcesses.getMap().size() > 0) {
9328            boolean printed = false;
9329            for (Map.Entry<String, SparseArray<Long>> procs
9330                    : mBadProcesses.getMap().entrySet()) {
9331                String pname = procs.getKey();
9332                SparseArray<Long> uids = procs.getValue();
9333                final int N = uids.size();
9334                for (int i=0; i<N; i++) {
9335                    int puid = uids.keyAt(i);
9336                    ProcessRecord r = mProcessNames.get(pname, puid);
9337                    if (dumpPackage != null && (r == null
9338                            || !dumpPackage.equals(r.info.packageName))) {
9339                        continue;
9340                    }
9341                    if (!printed) {
9342                        if (needSep) pw.println(" ");
9343                        needSep = true;
9344                        pw.println("  Bad processes:");
9345                    }
9346                    pw.print("    Bad process "); pw.print(pname);
9347                            pw.print(" uid "); pw.print(puid);
9348                            pw.print(": crashed at time ");
9349                            pw.println(uids.valueAt(i));
9350                }
9351            }
9352        }
9353
9354        pw.println();
9355        pw.println("  mStartedUsers:");
9356        for (int i=0; i<mStartedUsers.size(); i++) {
9357            UserStartedState uss = mStartedUsers.valueAt(i);
9358            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9359                    pw.print(": "); uss.dump("", pw);
9360        }
9361        pw.print("  mStartedUserArray: [");
9362        for (int i=0; i<mStartedUserArray.length; i++) {
9363            if (i > 0) pw.print(", ");
9364            pw.print(mStartedUserArray[i]);
9365        }
9366        pw.println("]");
9367        pw.print("  mUserLru: [");
9368        for (int i=0; i<mUserLru.size(); i++) {
9369            if (i > 0) pw.print(", ");
9370            pw.print(mUserLru.get(i));
9371        }
9372        pw.println("]");
9373        if (dumpAll) {
9374            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9375        }
9376        pw.println("  mHomeProcess: " + mHomeProcess);
9377        pw.println("  mPreviousProcess: " + mPreviousProcess);
9378        if (dumpAll) {
9379            StringBuilder sb = new StringBuilder(128);
9380            sb.append("  mPreviousProcessVisibleTime: ");
9381            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9382            pw.println(sb);
9383        }
9384        if (mHeavyWeightProcess != null) {
9385            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9386        }
9387        pw.println("  mConfiguration: " + mConfiguration);
9388        if (dumpAll) {
9389            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9390            if (mCompatModePackages.getPackages().size() > 0) {
9391                boolean printed = false;
9392                for (Map.Entry<String, Integer> entry
9393                        : mCompatModePackages.getPackages().entrySet()) {
9394                    String pkg = entry.getKey();
9395                    int mode = entry.getValue();
9396                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9397                        continue;
9398                    }
9399                    if (!printed) {
9400                        pw.println("  mScreenCompatPackages:");
9401                        printed = true;
9402                    }
9403                    pw.print("    "); pw.print(pkg); pw.print(": ");
9404                            pw.print(mode); pw.println();
9405                }
9406            }
9407        }
9408        if (mSleeping || mWentToSleep || mLockScreenShown) {
9409            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9410                    + " mLockScreenShown " + mLockScreenShown);
9411        }
9412        if (mShuttingDown) {
9413            pw.println("  mShuttingDown=" + mShuttingDown);
9414        }
9415        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9416                || mOrigWaitForDebugger) {
9417            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9418                    + " mDebugTransient=" + mDebugTransient
9419                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9420        }
9421        if (mOpenGlTraceApp != null) {
9422            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9423        }
9424        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9425                || mProfileFd != null) {
9426            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9427            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9428            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9429                    + mAutoStopProfiler);
9430        }
9431        if (mAlwaysFinishActivities || mController != null) {
9432            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9433                    + " mController=" + mController);
9434        }
9435        if (dumpAll) {
9436            pw.println("  Total persistent processes: " + numPers);
9437            pw.println("  mStartRunning=" + mStartRunning
9438                    + " mProcessesReady=" + mProcessesReady
9439                    + " mSystemReady=" + mSystemReady);
9440            pw.println("  mBooting=" + mBooting
9441                    + " mBooted=" + mBooted
9442                    + " mFactoryTest=" + mFactoryTest);
9443            pw.print("  mLastPowerCheckRealtime=");
9444                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9445                    pw.println("");
9446            pw.print("  mLastPowerCheckUptime=");
9447                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9448                    pw.println("");
9449            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9450            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9451            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9452            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9453                    + " mNumHiddenProcs=" + mNumHiddenProcs
9454                    + " mNumServiceProcs=" + mNumServiceProcs
9455                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9456        }
9457
9458        return true;
9459    }
9460
9461    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9462            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9463        if (mProcessesToGc.size() > 0) {
9464            boolean printed = false;
9465            long now = SystemClock.uptimeMillis();
9466            for (int i=0; i<mProcessesToGc.size(); i++) {
9467                ProcessRecord proc = mProcessesToGc.get(i);
9468                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9469                    continue;
9470                }
9471                if (!printed) {
9472                    if (needSep) pw.println(" ");
9473                    needSep = true;
9474                    pw.println("  Processes that are waiting to GC:");
9475                    printed = true;
9476                }
9477                pw.print("    Process "); pw.println(proc);
9478                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9479                        pw.print(", last gced=");
9480                        pw.print(now-proc.lastRequestedGc);
9481                        pw.print(" ms ago, last lowMem=");
9482                        pw.print(now-proc.lastLowMemory);
9483                        pw.println(" ms ago");
9484
9485            }
9486        }
9487        return needSep;
9488    }
9489
9490    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9491            int opti, boolean dumpAll) {
9492        boolean needSep = false;
9493
9494        if (mLruProcesses.size() > 0) {
9495            if (needSep) pw.println(" ");
9496            needSep = true;
9497            pw.println("  OOM levels:");
9498            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9499            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9500            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9501            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9502            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9503            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9504            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9505            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9506            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9507            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9508            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9509            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9510            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9511
9512            if (needSep) pw.println(" ");
9513            needSep = true;
9514            pw.println("  Process OOM control:");
9515            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9516                    "Proc", "PERS", true, null);
9517            needSep = true;
9518        }
9519
9520        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9521
9522        pw.println();
9523        pw.println("  mHomeProcess: " + mHomeProcess);
9524        pw.println("  mPreviousProcess: " + mPreviousProcess);
9525        if (mHeavyWeightProcess != null) {
9526            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9527        }
9528
9529        return true;
9530    }
9531
9532    /**
9533     * There are three ways to call this:
9534     *  - no provider specified: dump all the providers
9535     *  - a flattened component name that matched an existing provider was specified as the
9536     *    first arg: dump that one provider
9537     *  - the first arg isn't the flattened component name of an existing provider:
9538     *    dump all providers whose component contains the first arg as a substring
9539     */
9540    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9541            int opti, boolean dumpAll) {
9542        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9543    }
9544
9545    static class ItemMatcher {
9546        ArrayList<ComponentName> components;
9547        ArrayList<String> strings;
9548        ArrayList<Integer> objects;
9549        boolean all;
9550
9551        ItemMatcher() {
9552            all = true;
9553        }
9554
9555        void build(String name) {
9556            ComponentName componentName = ComponentName.unflattenFromString(name);
9557            if (componentName != null) {
9558                if (components == null) {
9559                    components = new ArrayList<ComponentName>();
9560                }
9561                components.add(componentName);
9562                all = false;
9563            } else {
9564                int objectId = 0;
9565                // Not a '/' separated full component name; maybe an object ID?
9566                try {
9567                    objectId = Integer.parseInt(name, 16);
9568                    if (objects == null) {
9569                        objects = new ArrayList<Integer>();
9570                    }
9571                    objects.add(objectId);
9572                    all = false;
9573                } catch (RuntimeException e) {
9574                    // Not an integer; just do string match.
9575                    if (strings == null) {
9576                        strings = new ArrayList<String>();
9577                    }
9578                    strings.add(name);
9579                    all = false;
9580                }
9581            }
9582        }
9583
9584        int build(String[] args, int opti) {
9585            for (; opti<args.length; opti++) {
9586                String name = args[opti];
9587                if ("--".equals(name)) {
9588                    return opti+1;
9589                }
9590                build(name);
9591            }
9592            return opti;
9593        }
9594
9595        boolean match(Object object, ComponentName comp) {
9596            if (all) {
9597                return true;
9598            }
9599            if (components != null) {
9600                for (int i=0; i<components.size(); i++) {
9601                    if (components.get(i).equals(comp)) {
9602                        return true;
9603                    }
9604                }
9605            }
9606            if (objects != null) {
9607                for (int i=0; i<objects.size(); i++) {
9608                    if (System.identityHashCode(object) == objects.get(i)) {
9609                        return true;
9610                    }
9611                }
9612            }
9613            if (strings != null) {
9614                String flat = comp.flattenToString();
9615                for (int i=0; i<strings.size(); i++) {
9616                    if (flat.contains(strings.get(i))) {
9617                        return true;
9618                    }
9619                }
9620            }
9621            return false;
9622        }
9623    }
9624
9625    /**
9626     * There are three things that cmd can be:
9627     *  - a flattened component name that matches an existing activity
9628     *  - the cmd arg isn't the flattened component name of an existing activity:
9629     *    dump all activity whose component contains the cmd as a substring
9630     *  - A hex number of the ActivityRecord object instance.
9631     */
9632    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9633            int opti, boolean dumpAll) {
9634        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9635
9636        if ("all".equals(name)) {
9637            synchronized (this) {
9638                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9639                    activities.add(r1);
9640                }
9641            }
9642        } else if ("top".equals(name)) {
9643            synchronized (this) {
9644                final int N = mMainStack.mHistory.size();
9645                if (N > 0) {
9646                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9647                }
9648            }
9649        } else {
9650            ItemMatcher matcher = new ItemMatcher();
9651            matcher.build(name);
9652
9653            synchronized (this) {
9654                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9655                    if (matcher.match(r1, r1.intent.getComponent())) {
9656                        activities.add(r1);
9657                    }
9658                }
9659            }
9660        }
9661
9662        if (activities.size() <= 0) {
9663            return false;
9664        }
9665
9666        String[] newArgs = new String[args.length - opti];
9667        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9668
9669        TaskRecord lastTask = null;
9670        boolean needSep = false;
9671        for (int i=activities.size()-1; i>=0; i--) {
9672            ActivityRecord r = (ActivityRecord)activities.get(i);
9673            if (needSep) {
9674                pw.println();
9675            }
9676            needSep = true;
9677            synchronized (this) {
9678                if (lastTask != r.task) {
9679                    lastTask = r.task;
9680                    pw.print("TASK "); pw.print(lastTask.affinity);
9681                            pw.print(" id="); pw.println(lastTask.taskId);
9682                    if (dumpAll) {
9683                        lastTask.dump(pw, "  ");
9684                    }
9685                }
9686            }
9687            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9688        }
9689        return true;
9690    }
9691
9692    /**
9693     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9694     * there is a thread associated with the activity.
9695     */
9696    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9697            final ActivityRecord r, String[] args, boolean dumpAll) {
9698        String innerPrefix = prefix + "  ";
9699        synchronized (this) {
9700            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9701                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9702                    pw.print(" pid=");
9703                    if (r.app != null) pw.println(r.app.pid);
9704                    else pw.println("(not running)");
9705            if (dumpAll) {
9706                r.dump(pw, innerPrefix);
9707            }
9708        }
9709        if (r.app != null && r.app.thread != null) {
9710            // flush anything that is already in the PrintWriter since the thread is going
9711            // to write to the file descriptor directly
9712            pw.flush();
9713            try {
9714                TransferPipe tp = new TransferPipe();
9715                try {
9716                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9717                            r.appToken, innerPrefix, args);
9718                    tp.go(fd);
9719                } finally {
9720                    tp.kill();
9721                }
9722            } catch (IOException e) {
9723                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9724            } catch (RemoteException e) {
9725                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9726            }
9727        }
9728    }
9729
9730    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9731            int opti, boolean dumpAll, String dumpPackage) {
9732        boolean needSep = false;
9733        boolean onlyHistory = false;
9734
9735        if ("history".equals(dumpPackage)) {
9736            if (opti < args.length && "-s".equals(args[opti])) {
9737                dumpAll = false;
9738            }
9739            onlyHistory = true;
9740            dumpPackage = null;
9741        }
9742
9743        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9744        if (!onlyHistory && dumpAll) {
9745            if (mRegisteredReceivers.size() > 0) {
9746                boolean printed = false;
9747                Iterator it = mRegisteredReceivers.values().iterator();
9748                while (it.hasNext()) {
9749                    ReceiverList r = (ReceiverList)it.next();
9750                    if (dumpPackage != null && (r.app == null ||
9751                            !dumpPackage.equals(r.app.info.packageName))) {
9752                        continue;
9753                    }
9754                    if (!printed) {
9755                        pw.println("  Registered Receivers:");
9756                        needSep = true;
9757                        printed = true;
9758                    }
9759                    pw.print("  * "); pw.println(r);
9760                    r.dump(pw, "    ");
9761                }
9762            }
9763
9764            if (mReceiverResolver.dump(pw, needSep ?
9765                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9766                    "    ", dumpPackage, false)) {
9767                needSep = true;
9768            }
9769        }
9770
9771        for (BroadcastQueue q : mBroadcastQueues) {
9772            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9773        }
9774
9775        needSep = true;
9776
9777        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9778            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9779                if (needSep) {
9780                    pw.println();
9781                }
9782                needSep = true;
9783                pw.print("  Sticky broadcasts for user ");
9784                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9785                StringBuilder sb = new StringBuilder(128);
9786                for (Map.Entry<String, ArrayList<Intent>> ent
9787                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9788                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9789                    if (dumpAll) {
9790                        pw.println(":");
9791                        ArrayList<Intent> intents = ent.getValue();
9792                        final int N = intents.size();
9793                        for (int i=0; i<N; i++) {
9794                            sb.setLength(0);
9795                            sb.append("    Intent: ");
9796                            intents.get(i).toShortString(sb, false, true, false, false);
9797                            pw.println(sb.toString());
9798                            Bundle bundle = intents.get(i).getExtras();
9799                            if (bundle != null) {
9800                                pw.print("      ");
9801                                pw.println(bundle.toString());
9802                            }
9803                        }
9804                    } else {
9805                        pw.println("");
9806                    }
9807                }
9808            }
9809        }
9810
9811        if (!onlyHistory && dumpAll) {
9812            pw.println();
9813            for (BroadcastQueue queue : mBroadcastQueues) {
9814                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9815                        + queue.mBroadcastsScheduled);
9816            }
9817            pw.println("  mHandler:");
9818            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9819            needSep = true;
9820        }
9821
9822        return needSep;
9823    }
9824
9825    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9826            int opti, boolean dumpAll, String dumpPackage) {
9827        boolean needSep = true;
9828
9829        ItemMatcher matcher = new ItemMatcher();
9830        matcher.build(args, opti);
9831
9832        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9833
9834        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9835
9836        if (mLaunchingProviders.size() > 0) {
9837            boolean printed = false;
9838            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9839                ContentProviderRecord r = mLaunchingProviders.get(i);
9840                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9841                    continue;
9842                }
9843                if (!printed) {
9844                    if (needSep) pw.println(" ");
9845                    needSep = true;
9846                    pw.println("  Launching content providers:");
9847                    printed = true;
9848                }
9849                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9850                        pw.println(r);
9851            }
9852        }
9853
9854        if (mGrantedUriPermissions.size() > 0) {
9855            if (needSep) pw.println();
9856            needSep = true;
9857            pw.println("Granted Uri Permissions:");
9858            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9859                int uid = mGrantedUriPermissions.keyAt(i);
9860                HashMap<Uri, UriPermission> perms
9861                        = mGrantedUriPermissions.valueAt(i);
9862                pw.print("  * UID "); pw.print(uid);
9863                        pw.println(" holds:");
9864                for (UriPermission perm : perms.values()) {
9865                    pw.print("    "); pw.println(perm);
9866                    if (dumpAll) {
9867                        perm.dump(pw, "      ");
9868                    }
9869                }
9870            }
9871            needSep = true;
9872        }
9873
9874        return needSep;
9875    }
9876
9877    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9878            int opti, boolean dumpAll, String dumpPackage) {
9879        boolean needSep = false;
9880
9881        if (mIntentSenderRecords.size() > 0) {
9882            boolean printed = false;
9883            Iterator<WeakReference<PendingIntentRecord>> it
9884                    = mIntentSenderRecords.values().iterator();
9885            while (it.hasNext()) {
9886                WeakReference<PendingIntentRecord> ref = it.next();
9887                PendingIntentRecord rec = ref != null ? ref.get(): null;
9888                if (dumpPackage != null && (rec == null
9889                        || !dumpPackage.equals(rec.key.packageName))) {
9890                    continue;
9891                }
9892                if (!printed) {
9893                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9894                    printed = true;
9895                }
9896                needSep = true;
9897                if (rec != null) {
9898                    pw.print("  * "); pw.println(rec);
9899                    if (dumpAll) {
9900                        rec.dump(pw, "    ");
9901                    }
9902                } else {
9903                    pw.print("  * "); pw.println(ref);
9904                }
9905            }
9906        }
9907
9908        return needSep;
9909    }
9910
9911    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9912            String prefix, String label, boolean complete, boolean brief, boolean client,
9913            String dumpPackage) {
9914        TaskRecord lastTask = null;
9915        boolean needNL = false;
9916        final String innerPrefix = prefix + "      ";
9917        final String[] args = new String[0];
9918        for (int i=list.size()-1; i>=0; i--) {
9919            final ActivityRecord r = (ActivityRecord)list.get(i);
9920            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9921                continue;
9922            }
9923            final boolean full = !brief && (complete || !r.isInHistory());
9924            if (needNL) {
9925                pw.println(" ");
9926                needNL = false;
9927            }
9928            if (lastTask != r.task) {
9929                lastTask = r.task;
9930                pw.print(prefix);
9931                pw.print(full ? "* " : "  ");
9932                pw.println(lastTask);
9933                if (full) {
9934                    lastTask.dump(pw, prefix + "  ");
9935                } else if (complete) {
9936                    // Complete + brief == give a summary.  Isn't that obvious?!?
9937                    if (lastTask.intent != null) {
9938                        pw.print(prefix); pw.print("  ");
9939                                pw.println(lastTask.intent.toInsecureStringWithClip());
9940                    }
9941                }
9942            }
9943            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9944            pw.print(" #"); pw.print(i); pw.print(": ");
9945            pw.println(r);
9946            if (full) {
9947                r.dump(pw, innerPrefix);
9948            } else if (complete) {
9949                // Complete + brief == give a summary.  Isn't that obvious?!?
9950                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9951                if (r.app != null) {
9952                    pw.print(innerPrefix); pw.println(r.app);
9953                }
9954            }
9955            if (client && r.app != null && r.app.thread != null) {
9956                // flush anything that is already in the PrintWriter since the thread is going
9957                // to write to the file descriptor directly
9958                pw.flush();
9959                try {
9960                    TransferPipe tp = new TransferPipe();
9961                    try {
9962                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9963                                r.appToken, innerPrefix, args);
9964                        // Short timeout, since blocking here can
9965                        // deadlock with the application.
9966                        tp.go(fd, 2000);
9967                    } finally {
9968                        tp.kill();
9969                    }
9970                } catch (IOException e) {
9971                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9972                } catch (RemoteException e) {
9973                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9974                }
9975                needNL = true;
9976            }
9977        }
9978    }
9979
9980    private static String buildOomTag(String prefix, String space, int val, int base) {
9981        if (val == base) {
9982            if (space == null) return prefix;
9983            return prefix + "  ";
9984        }
9985        return prefix + "+" + Integer.toString(val-base);
9986    }
9987
9988    private static final int dumpProcessList(PrintWriter pw,
9989            ActivityManagerService service, List list,
9990            String prefix, String normalLabel, String persistentLabel,
9991            String dumpPackage) {
9992        int numPers = 0;
9993        final int N = list.size()-1;
9994        for (int i=N; i>=0; i--) {
9995            ProcessRecord r = (ProcessRecord)list.get(i);
9996            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9997                continue;
9998            }
9999            pw.println(String.format("%s%s #%2d: %s",
10000                    prefix, (r.persistent ? persistentLabel : normalLabel),
10001                    i, r.toString()));
10002            if (r.persistent) {
10003                numPers++;
10004            }
10005        }
10006        return numPers;
10007    }
10008
10009    private static final boolean dumpProcessOomList(PrintWriter pw,
10010            ActivityManagerService service, List<ProcessRecord> origList,
10011            String prefix, String normalLabel, String persistentLabel,
10012            boolean inclDetails, String dumpPackage) {
10013
10014        ArrayList<Pair<ProcessRecord, Integer>> list
10015                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10016        for (int i=0; i<origList.size(); i++) {
10017            ProcessRecord r = origList.get(i);
10018            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10019                continue;
10020            }
10021            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10022        }
10023
10024        if (list.size() <= 0) {
10025            return false;
10026        }
10027
10028        Comparator<Pair<ProcessRecord, Integer>> comparator
10029                = new Comparator<Pair<ProcessRecord, Integer>>() {
10030            @Override
10031            public int compare(Pair<ProcessRecord, Integer> object1,
10032                    Pair<ProcessRecord, Integer> object2) {
10033                if (object1.first.setAdj != object2.first.setAdj) {
10034                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10035                }
10036                if (object1.second.intValue() != object2.second.intValue()) {
10037                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10038                }
10039                return 0;
10040            }
10041        };
10042
10043        Collections.sort(list, comparator);
10044
10045        final long curRealtime = SystemClock.elapsedRealtime();
10046        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10047        final long curUptime = SystemClock.uptimeMillis();
10048        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10049
10050        for (int i=list.size()-1; i>=0; i--) {
10051            ProcessRecord r = list.get(i).first;
10052            String oomAdj;
10053            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10054                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10055            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10056                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10057            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10058                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10059            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10060                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10061            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10062                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10063            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10064                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10065            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10066                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10067            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10068                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10069            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10070                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10071            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10072                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10073            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10074                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10075            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10076                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10077            } else {
10078                oomAdj = Integer.toString(r.setAdj);
10079            }
10080            String schedGroup;
10081            switch (r.setSchedGroup) {
10082                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10083                    schedGroup = "B";
10084                    break;
10085                case Process.THREAD_GROUP_DEFAULT:
10086                    schedGroup = "F";
10087                    break;
10088                default:
10089                    schedGroup = Integer.toString(r.setSchedGroup);
10090                    break;
10091            }
10092            String foreground;
10093            if (r.foregroundActivities) {
10094                foreground = "A";
10095            } else if (r.foregroundServices) {
10096                foreground = "S";
10097            } else {
10098                foreground = " ";
10099            }
10100            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10101                    prefix, (r.persistent ? persistentLabel : normalLabel),
10102                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10103                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10104            if (r.adjSource != null || r.adjTarget != null) {
10105                pw.print(prefix);
10106                pw.print("    ");
10107                if (r.adjTarget instanceof ComponentName) {
10108                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10109                } else if (r.adjTarget != null) {
10110                    pw.print(r.adjTarget.toString());
10111                } else {
10112                    pw.print("{null}");
10113                }
10114                pw.print("<=");
10115                if (r.adjSource instanceof ProcessRecord) {
10116                    pw.print("Proc{");
10117                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10118                    pw.println("}");
10119                } else if (r.adjSource != null) {
10120                    pw.println(r.adjSource.toString());
10121                } else {
10122                    pw.println("{null}");
10123                }
10124            }
10125            if (inclDetails) {
10126                pw.print(prefix);
10127                pw.print("    ");
10128                pw.print("oom: max="); pw.print(r.maxAdj);
10129                pw.print(" hidden="); pw.print(r.hiddenAdj);
10130                pw.print(" client="); pw.print(r.clientHiddenAdj);
10131                pw.print(" empty="); pw.print(r.emptyAdj);
10132                pw.print(" curRaw="); pw.print(r.curRawAdj);
10133                pw.print(" setRaw="); pw.print(r.setRawAdj);
10134                pw.print(" cur="); pw.print(r.curAdj);
10135                pw.print(" set="); pw.println(r.setAdj);
10136                pw.print(prefix);
10137                pw.print("    ");
10138                pw.print("keeping="); pw.print(r.keeping);
10139                pw.print(" hidden="); pw.print(r.hidden);
10140                pw.print(" empty="); pw.print(r.empty);
10141                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10142
10143                if (!r.keeping) {
10144                    if (r.lastWakeTime != 0) {
10145                        long wtime;
10146                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10147                        synchronized (stats) {
10148                            wtime = stats.getProcessWakeTime(r.info.uid,
10149                                    r.pid, curRealtime);
10150                        }
10151                        long timeUsed = wtime - r.lastWakeTime;
10152                        pw.print(prefix);
10153                        pw.print("    ");
10154                        pw.print("keep awake over ");
10155                        TimeUtils.formatDuration(realtimeSince, pw);
10156                        pw.print(" used ");
10157                        TimeUtils.formatDuration(timeUsed, pw);
10158                        pw.print(" (");
10159                        pw.print((timeUsed*100)/realtimeSince);
10160                        pw.println("%)");
10161                    }
10162                    if (r.lastCpuTime != 0) {
10163                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10164                        pw.print(prefix);
10165                        pw.print("    ");
10166                        pw.print("run cpu over ");
10167                        TimeUtils.formatDuration(uptimeSince, pw);
10168                        pw.print(" used ");
10169                        TimeUtils.formatDuration(timeUsed, pw);
10170                        pw.print(" (");
10171                        pw.print((timeUsed*100)/uptimeSince);
10172                        pw.println("%)");
10173                    }
10174                }
10175            }
10176        }
10177        return true;
10178    }
10179
10180    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10181        ArrayList<ProcessRecord> procs;
10182        synchronized (this) {
10183            if (args != null && args.length > start
10184                    && args[start].charAt(0) != '-') {
10185                procs = new ArrayList<ProcessRecord>();
10186                int pid = -1;
10187                try {
10188                    pid = Integer.parseInt(args[start]);
10189                } catch (NumberFormatException e) {
10190
10191                }
10192                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10193                    ProcessRecord proc = mLruProcesses.get(i);
10194                    if (proc.pid == pid) {
10195                        procs.add(proc);
10196                    } else if (proc.processName.equals(args[start])) {
10197                        procs.add(proc);
10198                    }
10199                }
10200                if (procs.size() <= 0) {
10201                    pw.println("No process found for: " + args[start]);
10202                    return null;
10203                }
10204            } else {
10205                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10206            }
10207        }
10208        return procs;
10209    }
10210
10211    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10212            PrintWriter pw, String[] args) {
10213        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10214        if (procs == null) {
10215            return;
10216        }
10217
10218        long uptime = SystemClock.uptimeMillis();
10219        long realtime = SystemClock.elapsedRealtime();
10220        pw.println("Applications Graphics Acceleration Info:");
10221        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10222
10223        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10224            ProcessRecord r = procs.get(i);
10225            if (r.thread != null) {
10226                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10227                pw.flush();
10228                try {
10229                    TransferPipe tp = new TransferPipe();
10230                    try {
10231                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10232                        tp.go(fd);
10233                    } finally {
10234                        tp.kill();
10235                    }
10236                } catch (IOException e) {
10237                    pw.println("Failure while dumping the app: " + r);
10238                    pw.flush();
10239                } catch (RemoteException e) {
10240                    pw.println("Got a RemoteException while dumping the app " + r);
10241                    pw.flush();
10242                }
10243            }
10244        }
10245    }
10246
10247    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10248        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10249        if (procs == null) {
10250            return;
10251        }
10252
10253        pw.println("Applications Database Info:");
10254
10255        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10256            ProcessRecord r = procs.get(i);
10257            if (r.thread != null) {
10258                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10259                pw.flush();
10260                try {
10261                    TransferPipe tp = new TransferPipe();
10262                    try {
10263                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10264                        tp.go(fd);
10265                    } finally {
10266                        tp.kill();
10267                    }
10268                } catch (IOException e) {
10269                    pw.println("Failure while dumping the app: " + r);
10270                    pw.flush();
10271                } catch (RemoteException e) {
10272                    pw.println("Got a RemoteException while dumping the app " + r);
10273                    pw.flush();
10274                }
10275            }
10276        }
10277    }
10278
10279    final static class MemItem {
10280        final String label;
10281        final String shortLabel;
10282        final long pss;
10283        final int id;
10284        ArrayList<MemItem> subitems;
10285
10286        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10287            label = _label;
10288            shortLabel = _shortLabel;
10289            pss = _pss;
10290            id = _id;
10291        }
10292    }
10293
10294    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10295            boolean sort) {
10296        if (sort) {
10297            Collections.sort(items, new Comparator<MemItem>() {
10298                @Override
10299                public int compare(MemItem lhs, MemItem rhs) {
10300                    if (lhs.pss < rhs.pss) {
10301                        return 1;
10302                    } else if (lhs.pss > rhs.pss) {
10303                        return -1;
10304                    }
10305                    return 0;
10306                }
10307            });
10308        }
10309
10310        for (int i=0; i<items.size(); i++) {
10311            MemItem mi = items.get(i);
10312            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10313            if (mi.subitems != null) {
10314                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10315            }
10316        }
10317    }
10318
10319    // These are in KB.
10320    static final long[] DUMP_MEM_BUCKETS = new long[] {
10321        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10322        120*1024, 160*1024, 200*1024,
10323        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10324        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10325    };
10326
10327    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10328            boolean stackLike) {
10329        int start = label.lastIndexOf('.');
10330        if (start >= 0) start++;
10331        else start = 0;
10332        int end = label.length();
10333        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10334            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10335                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10336                out.append(bucket);
10337                out.append(stackLike ? "MB." : "MB ");
10338                out.append(label, start, end);
10339                return;
10340            }
10341        }
10342        out.append(memKB/1024);
10343        out.append(stackLike ? "MB." : "MB ");
10344        out.append(label, start, end);
10345    }
10346
10347    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10348            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10349            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10350            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10351            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10352    };
10353    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10354            "System", "Persistent", "Foreground",
10355            "Visible", "Perceptible", "Heavy Weight",
10356            "Backup", "A Services", "Home", "Previous",
10357            "B Services", "Background"
10358    };
10359
10360    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10361            PrintWriter pw, String prefix, String[] args, boolean brief,
10362            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10363        boolean dumpAll = false;
10364        boolean oomOnly = false;
10365
10366        int opti = 0;
10367        while (opti < args.length) {
10368            String opt = args[opti];
10369            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10370                break;
10371            }
10372            opti++;
10373            if ("-a".equals(opt)) {
10374                dumpAll = true;
10375            } else if ("--oom".equals(opt)) {
10376                oomOnly = true;
10377            } else if ("-h".equals(opt)) {
10378                pw.println("meminfo dump options: [-a] [--oom] [process]");
10379                pw.println("  -a: include all available information for each process.");
10380                pw.println("  --oom: only show processes organized by oom adj.");
10381                pw.println("If [process] is specified it can be the name or ");
10382                pw.println("pid of a specific process to dump.");
10383                return;
10384            } else {
10385                pw.println("Unknown argument: " + opt + "; use -h for help");
10386            }
10387        }
10388
10389        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10390        if (procs == null) {
10391            return;
10392        }
10393
10394        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10395        long uptime = SystemClock.uptimeMillis();
10396        long realtime = SystemClock.elapsedRealtime();
10397
10398        if (procs.size() == 1 || isCheckinRequest) {
10399            dumpAll = true;
10400        }
10401
10402        if (isCheckinRequest) {
10403            // short checkin version
10404            pw.println(uptime + "," + realtime);
10405            pw.flush();
10406        } else {
10407            pw.println("Applications Memory Usage (kB):");
10408            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10409        }
10410
10411        String[] innerArgs = new String[args.length-opti];
10412        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10413
10414        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10415        long nativePss=0, dalvikPss=0, otherPss=0;
10416        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10417
10418        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10419        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10420                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10421
10422        long totalPss = 0;
10423
10424        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10425            ProcessRecord r = procs.get(i);
10426            if (r.thread != null) {
10427                if (!isCheckinRequest && dumpAll) {
10428                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10429                    pw.flush();
10430                }
10431                Debug.MemoryInfo mi = null;
10432                if (dumpAll) {
10433                    try {
10434                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10435                    } catch (RemoteException e) {
10436                        if (!isCheckinRequest) {
10437                            pw.println("Got RemoteException!");
10438                            pw.flush();
10439                        }
10440                    }
10441                } else {
10442                    mi = new Debug.MemoryInfo();
10443                    Debug.getMemoryInfo(r.pid, mi);
10444                }
10445
10446                if (!isCheckinRequest && mi != null) {
10447                    long myTotalPss = mi.getTotalPss();
10448                    totalPss += myTotalPss;
10449                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10450                            r.processName, myTotalPss, 0);
10451                    procMems.add(pssItem);
10452
10453                    nativePss += mi.nativePss;
10454                    dalvikPss += mi.dalvikPss;
10455                    otherPss += mi.otherPss;
10456                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10457                        long mem = mi.getOtherPss(j);
10458                        miscPss[j] += mem;
10459                        otherPss -= mem;
10460                    }
10461
10462                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10463                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10464                                || oomIndex == (oomPss.length-1)) {
10465                            oomPss[oomIndex] += myTotalPss;
10466                            if (oomProcs[oomIndex] == null) {
10467                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10468                            }
10469                            oomProcs[oomIndex].add(pssItem);
10470                            break;
10471                        }
10472                    }
10473                }
10474            }
10475        }
10476
10477        if (!isCheckinRequest && procs.size() > 1) {
10478            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10479
10480            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10481            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10482            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10483            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10484                String label = Debug.MemoryInfo.getOtherLabel(j);
10485                catMems.add(new MemItem(label, label, miscPss[j], j));
10486            }
10487
10488            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10489            for (int j=0; j<oomPss.length; j++) {
10490                if (oomPss[j] != 0) {
10491                    String label = DUMP_MEM_OOM_LABEL[j];
10492                    MemItem item = new MemItem(label, label, oomPss[j],
10493                            DUMP_MEM_OOM_ADJ[j]);
10494                    item.subitems = oomProcs[j];
10495                    oomMems.add(item);
10496                }
10497            }
10498
10499            if (outTag != null || outStack != null) {
10500                if (outTag != null) {
10501                    appendMemBucket(outTag, totalPss, "total", false);
10502                }
10503                if (outStack != null) {
10504                    appendMemBucket(outStack, totalPss, "total", true);
10505                }
10506                boolean firstLine = true;
10507                for (int i=0; i<oomMems.size(); i++) {
10508                    MemItem miCat = oomMems.get(i);
10509                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10510                        continue;
10511                    }
10512                    if (miCat.id < ProcessList.SERVICE_ADJ
10513                            || miCat.id == ProcessList.HOME_APP_ADJ
10514                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10515                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10516                            outTag.append(" / ");
10517                        }
10518                        if (outStack != null) {
10519                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10520                                if (firstLine) {
10521                                    outStack.append(":");
10522                                    firstLine = false;
10523                                }
10524                                outStack.append("\n\t at ");
10525                            } else {
10526                                outStack.append("$");
10527                            }
10528                        }
10529                        for (int j=0; j<miCat.subitems.size(); j++) {
10530                            MemItem mi = miCat.subitems.get(j);
10531                            if (j > 0) {
10532                                if (outTag != null) {
10533                                    outTag.append(" ");
10534                                }
10535                                if (outStack != null) {
10536                                    outStack.append("$");
10537                                }
10538                            }
10539                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10540                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10541                            }
10542                            if (outStack != null) {
10543                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10544                            }
10545                        }
10546                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10547                            outStack.append("(");
10548                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10549                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10550                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10551                                    outStack.append(":");
10552                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10553                                }
10554                            }
10555                            outStack.append(")");
10556                        }
10557                    }
10558                }
10559            }
10560
10561            if (!brief && !oomOnly) {
10562                pw.println();
10563                pw.println("Total PSS by process:");
10564                dumpMemItems(pw, "  ", procMems, true);
10565                pw.println();
10566            }
10567            pw.println("Total PSS by OOM adjustment:");
10568            dumpMemItems(pw, "  ", oomMems, false);
10569            if (!oomOnly) {
10570                PrintWriter out = categoryPw != null ? categoryPw : pw;
10571                out.println();
10572                out.println("Total PSS by category:");
10573                dumpMemItems(out, "  ", catMems, true);
10574            }
10575            pw.println();
10576            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10577            final int[] SINGLE_LONG_FORMAT = new int[] {
10578                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10579            };
10580            long[] longOut = new long[1];
10581            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10582                    SINGLE_LONG_FORMAT, null, longOut, null);
10583            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10584            longOut[0] = 0;
10585            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10586                    SINGLE_LONG_FORMAT, null, longOut, null);
10587            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10588            longOut[0] = 0;
10589            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10590                    SINGLE_LONG_FORMAT, null, longOut, null);
10591            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10592            longOut[0] = 0;
10593            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10594                    SINGLE_LONG_FORMAT, null, longOut, null);
10595            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10596            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10597                    pw.print(shared); pw.println(" kB");
10598            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10599                    pw.print(voltile); pw.println(" kB volatile");
10600        }
10601    }
10602
10603    /**
10604     * Searches array of arguments for the specified string
10605     * @param args array of argument strings
10606     * @param value value to search for
10607     * @return true if the value is contained in the array
10608     */
10609    private static boolean scanArgs(String[] args, String value) {
10610        if (args != null) {
10611            for (String arg : args) {
10612                if (value.equals(arg)) {
10613                    return true;
10614                }
10615            }
10616        }
10617        return false;
10618    }
10619
10620    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10621            ContentProviderRecord cpr, boolean always) {
10622        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10623
10624        if (!inLaunching || always) {
10625            synchronized (cpr) {
10626                cpr.launchingApp = null;
10627                cpr.notifyAll();
10628            }
10629            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10630            String names[] = cpr.info.authority.split(";");
10631            for (int j = 0; j < names.length; j++) {
10632                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10633            }
10634        }
10635
10636        for (int i=0; i<cpr.connections.size(); i++) {
10637            ContentProviderConnection conn = cpr.connections.get(i);
10638            if (conn.waiting) {
10639                // If this connection is waiting for the provider, then we don't
10640                // need to mess with its process unless we are always removing
10641                // or for some reason the provider is not currently launching.
10642                if (inLaunching && !always) {
10643                    continue;
10644                }
10645            }
10646            ProcessRecord capp = conn.client;
10647            conn.dead = true;
10648            if (conn.stableCount > 0) {
10649                if (!capp.persistent && capp.thread != null
10650                        && capp.pid != 0
10651                        && capp.pid != MY_PID) {
10652                    Slog.i(TAG, "Kill " + capp.processName
10653                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10654                            + " in dying process " + (proc != null ? proc.processName : "??"));
10655                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10656                            capp.processName, capp.setAdj, "dying provider "
10657                                    + cpr.name.toShortString());
10658                    Process.killProcessQuiet(capp.pid);
10659                }
10660            } else if (capp.thread != null && conn.provider.provider != null) {
10661                try {
10662                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10663                } catch (RemoteException e) {
10664                }
10665                // In the protocol here, we don't expect the client to correctly
10666                // clean up this connection, we'll just remove it.
10667                cpr.connections.remove(i);
10668                conn.client.conProviders.remove(conn);
10669            }
10670        }
10671
10672        if (inLaunching && always) {
10673            mLaunchingProviders.remove(cpr);
10674        }
10675        return inLaunching;
10676    }
10677
10678    /**
10679     * Main code for cleaning up a process when it has gone away.  This is
10680     * called both as a result of the process dying, or directly when stopping
10681     * a process when running in single process mode.
10682     */
10683    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10684            boolean restarting, boolean allowRestart, int index) {
10685        if (index >= 0) {
10686            mLruProcesses.remove(index);
10687        }
10688
10689        mProcessesToGc.remove(app);
10690
10691        // Dismiss any open dialogs.
10692        if (app.crashDialog != null) {
10693            app.crashDialog.dismiss();
10694            app.crashDialog = null;
10695        }
10696        if (app.anrDialog != null) {
10697            app.anrDialog.dismiss();
10698            app.anrDialog = null;
10699        }
10700        if (app.waitDialog != null) {
10701            app.waitDialog.dismiss();
10702            app.waitDialog = null;
10703        }
10704
10705        app.crashing = false;
10706        app.notResponding = false;
10707
10708        app.resetPackageList();
10709        app.unlinkDeathRecipient();
10710        app.thread = null;
10711        app.forcingToForeground = null;
10712        app.foregroundServices = false;
10713        app.foregroundActivities = false;
10714        app.hasShownUi = false;
10715        app.hasAboveClient = false;
10716
10717        mServices.killServicesLocked(app, allowRestart);
10718
10719        boolean restart = false;
10720
10721        // Remove published content providers.
10722        if (!app.pubProviders.isEmpty()) {
10723            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10724            while (it.hasNext()) {
10725                ContentProviderRecord cpr = it.next();
10726
10727                final boolean always = app.bad || !allowRestart;
10728                if (removeDyingProviderLocked(app, cpr, always) || always) {
10729                    // We left the provider in the launching list, need to
10730                    // restart it.
10731                    restart = true;
10732                }
10733
10734                cpr.provider = null;
10735                cpr.proc = null;
10736            }
10737            app.pubProviders.clear();
10738        }
10739
10740        // Take care of any launching providers waiting for this process.
10741        if (checkAppInLaunchingProvidersLocked(app, false)) {
10742            restart = true;
10743        }
10744
10745        // Unregister from connected content providers.
10746        if (!app.conProviders.isEmpty()) {
10747            for (int i=0; i<app.conProviders.size(); i++) {
10748                ContentProviderConnection conn = app.conProviders.get(i);
10749                conn.provider.connections.remove(conn);
10750            }
10751            app.conProviders.clear();
10752        }
10753
10754        // At this point there may be remaining entries in mLaunchingProviders
10755        // where we were the only one waiting, so they are no longer of use.
10756        // Look for these and clean up if found.
10757        // XXX Commented out for now.  Trying to figure out a way to reproduce
10758        // the actual situation to identify what is actually going on.
10759        if (false) {
10760            for (int i=0; i<mLaunchingProviders.size(); i++) {
10761                ContentProviderRecord cpr = (ContentProviderRecord)
10762                        mLaunchingProviders.get(i);
10763                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10764                    synchronized (cpr) {
10765                        cpr.launchingApp = null;
10766                        cpr.notifyAll();
10767                    }
10768                }
10769            }
10770        }
10771
10772        skipCurrentReceiverLocked(app);
10773
10774        // Unregister any receivers.
10775        if (app.receivers.size() > 0) {
10776            Iterator<ReceiverList> it = app.receivers.iterator();
10777            while (it.hasNext()) {
10778                removeReceiverLocked(it.next());
10779            }
10780            app.receivers.clear();
10781        }
10782
10783        // If the app is undergoing backup, tell the backup manager about it
10784        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10785            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10786                    + mBackupTarget.appInfo + " died during backup");
10787            try {
10788                IBackupManager bm = IBackupManager.Stub.asInterface(
10789                        ServiceManager.getService(Context.BACKUP_SERVICE));
10790                bm.agentDisconnected(app.info.packageName);
10791            } catch (RemoteException e) {
10792                // can't happen; backup manager is local
10793            }
10794        }
10795
10796        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10797            ProcessChangeItem item = mPendingProcessChanges.get(i);
10798            if (item.pid == app.pid) {
10799                mPendingProcessChanges.remove(i);
10800                mAvailProcessChanges.add(item);
10801            }
10802        }
10803        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10804
10805        // If the caller is restarting this app, then leave it in its
10806        // current lists and let the caller take care of it.
10807        if (restarting) {
10808            return;
10809        }
10810
10811        if (!app.persistent || app.isolated) {
10812            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10813                    "Removing non-persistent process during cleanup: " + app);
10814            mProcessNames.remove(app.processName, app.uid);
10815            mIsolatedProcesses.remove(app.uid);
10816            if (mHeavyWeightProcess == app) {
10817                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10818                        mHeavyWeightProcess.userId, 0));
10819                mHeavyWeightProcess = null;
10820            }
10821        } else if (!app.removed) {
10822            // This app is persistent, so we need to keep its record around.
10823            // If it is not already on the pending app list, add it there
10824            // and start a new process for it.
10825            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10826                mPersistentStartingProcesses.add(app);
10827                restart = true;
10828            }
10829        }
10830        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10831                "Clean-up removing on hold: " + app);
10832        mProcessesOnHold.remove(app);
10833
10834        if (app == mHomeProcess) {
10835            mHomeProcess = null;
10836        }
10837        if (app == mPreviousProcess) {
10838            mPreviousProcess = null;
10839        }
10840
10841        if (restart && !app.isolated) {
10842            // We have components that still need to be running in the
10843            // process, so re-launch it.
10844            mProcessNames.put(app.processName, app.uid, app);
10845            startProcessLocked(app, "restart", app.processName);
10846        } else if (app.pid > 0 && app.pid != MY_PID) {
10847            // Goodbye!
10848            synchronized (mPidsSelfLocked) {
10849                mPidsSelfLocked.remove(app.pid);
10850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10851            }
10852            app.setPid(0);
10853        }
10854    }
10855
10856    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10857        // Look through the content providers we are waiting to have launched,
10858        // and if any run in this process then either schedule a restart of
10859        // the process or kill the client waiting for it if this process has
10860        // gone bad.
10861        int NL = mLaunchingProviders.size();
10862        boolean restart = false;
10863        for (int i=0; i<NL; i++) {
10864            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10865            if (cpr.launchingApp == app) {
10866                if (!alwaysBad && !app.bad) {
10867                    restart = true;
10868                } else {
10869                    removeDyingProviderLocked(app, cpr, true);
10870                    // cpr should have been removed from mLaunchingProviders
10871                    NL = mLaunchingProviders.size();
10872                    i--;
10873                }
10874            }
10875        }
10876        return restart;
10877    }
10878
10879    // =========================================================
10880    // SERVICES
10881    // =========================================================
10882
10883    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10884            int flags) {
10885        enforceNotIsolatedCaller("getServices");
10886        synchronized (this) {
10887            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10888        }
10889    }
10890
10891    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10892        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10893        synchronized (this) {
10894            return mServices.getRunningServiceControlPanelLocked(name);
10895        }
10896    }
10897
10898    public ComponentName startService(IApplicationThread caller, Intent service,
10899            String resolvedType, int userId) {
10900        enforceNotIsolatedCaller("startService");
10901        // Refuse possible leaked file descriptors
10902        if (service != null && service.hasFileDescriptors() == true) {
10903            throw new IllegalArgumentException("File descriptors passed in Intent");
10904        }
10905
10906        if (DEBUG_SERVICE)
10907            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10908        synchronized(this) {
10909            final int callingPid = Binder.getCallingPid();
10910            final int callingUid = Binder.getCallingUid();
10911            checkValidCaller(callingUid, userId);
10912            final long origId = Binder.clearCallingIdentity();
10913            ComponentName res = mServices.startServiceLocked(caller, service,
10914                    resolvedType, callingPid, callingUid, userId);
10915            Binder.restoreCallingIdentity(origId);
10916            return res;
10917        }
10918    }
10919
10920    ComponentName startServiceInPackage(int uid,
10921            Intent service, String resolvedType, int userId) {
10922        synchronized(this) {
10923            if (DEBUG_SERVICE)
10924                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10925            final long origId = Binder.clearCallingIdentity();
10926            ComponentName res = mServices.startServiceLocked(null, service,
10927                    resolvedType, -1, uid, userId);
10928            Binder.restoreCallingIdentity(origId);
10929            return res;
10930        }
10931    }
10932
10933    public int stopService(IApplicationThread caller, Intent service,
10934            String resolvedType, int userId) {
10935        enforceNotIsolatedCaller("stopService");
10936        // Refuse possible leaked file descriptors
10937        if (service != null && service.hasFileDescriptors() == true) {
10938            throw new IllegalArgumentException("File descriptors passed in Intent");
10939        }
10940
10941        checkValidCaller(Binder.getCallingUid(), userId);
10942
10943        synchronized(this) {
10944            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10945        }
10946    }
10947
10948    public IBinder peekService(Intent service, String resolvedType) {
10949        enforceNotIsolatedCaller("peekService");
10950        // Refuse possible leaked file descriptors
10951        if (service != null && service.hasFileDescriptors() == true) {
10952            throw new IllegalArgumentException("File descriptors passed in Intent");
10953        }
10954        synchronized(this) {
10955            return mServices.peekServiceLocked(service, resolvedType);
10956        }
10957    }
10958
10959    public boolean stopServiceToken(ComponentName className, IBinder token,
10960            int startId) {
10961        synchronized(this) {
10962            return mServices.stopServiceTokenLocked(className, token, startId);
10963        }
10964    }
10965
10966    public void setServiceForeground(ComponentName className, IBinder token,
10967            int id, Notification notification, boolean removeNotification) {
10968        synchronized(this) {
10969            mServices.setServiceForegroundLocked(className, token, id, notification,
10970                    removeNotification);
10971        }
10972    }
10973
10974    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10975            boolean requireFull, String name, String callerPackage) {
10976        final int callingUserId = UserHandle.getUserId(callingUid);
10977        if (callingUserId != userId) {
10978            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10979                if ((requireFull || checkComponentPermission(
10980                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10981                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10982                        && checkComponentPermission(
10983                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10984                                callingPid, callingUid, -1, true)
10985                                != PackageManager.PERMISSION_GRANTED) {
10986                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10987                        // In this case, they would like to just execute as their
10988                        // owner user instead of failing.
10989                        userId = callingUserId;
10990                    } else {
10991                        StringBuilder builder = new StringBuilder(128);
10992                        builder.append("Permission Denial: ");
10993                        builder.append(name);
10994                        if (callerPackage != null) {
10995                            builder.append(" from ");
10996                            builder.append(callerPackage);
10997                        }
10998                        builder.append(" asks to run as user ");
10999                        builder.append(userId);
11000                        builder.append(" but is calling from user ");
11001                        builder.append(UserHandle.getUserId(callingUid));
11002                        builder.append("; this requires ");
11003                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11004                        if (!requireFull) {
11005                            builder.append(" or ");
11006                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11007                        }
11008                        String msg = builder.toString();
11009                        Slog.w(TAG, msg);
11010                        throw new SecurityException(msg);
11011                    }
11012                }
11013            }
11014            if (userId == UserHandle.USER_CURRENT
11015                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
11016                // Note that we may be accessing this outside of a lock...
11017                // shouldn't be a big deal, if this is being called outside
11018                // of a locked context there is intrinsically a race with
11019                // the value the caller will receive and someone else changing it.
11020                userId = mCurrentUserId;
11021            }
11022            if (!allowAll && userId < 0) {
11023                throw new IllegalArgumentException(
11024                        "Call does not support special user #" + userId);
11025            }
11026        }
11027        return userId;
11028    }
11029
11030    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11031            String className, int flags) {
11032        boolean result = false;
11033        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11034            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11035                if (ActivityManager.checkUidPermission(
11036                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11037                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11038                    ComponentName comp = new ComponentName(aInfo.packageName, className);
11039                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
11040                            + " requests FLAG_SINGLE_USER, but app does not hold "
11041                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11042                    Slog.w(TAG, msg);
11043                    throw new SecurityException(msg);
11044                }
11045                result = true;
11046            }
11047        } else if (componentProcessName == aInfo.packageName) {
11048            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11049        } else if ("system".equals(componentProcessName)) {
11050            result = true;
11051        }
11052        if (DEBUG_MU) {
11053            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11054                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11055        }
11056        return result;
11057    }
11058
11059    public int bindService(IApplicationThread caller, IBinder token,
11060            Intent service, String resolvedType,
11061            IServiceConnection connection, int flags, int userId) {
11062        enforceNotIsolatedCaller("bindService");
11063        // Refuse possible leaked file descriptors
11064        if (service != null && service.hasFileDescriptors() == true) {
11065            throw new IllegalArgumentException("File descriptors passed in Intent");
11066        }
11067
11068        synchronized(this) {
11069            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11070                    connection, flags, userId);
11071        }
11072    }
11073
11074    public boolean unbindService(IServiceConnection connection) {
11075        synchronized (this) {
11076            return mServices.unbindServiceLocked(connection);
11077        }
11078    }
11079
11080    public void publishService(IBinder token, Intent intent, IBinder service) {
11081        // Refuse possible leaked file descriptors
11082        if (intent != null && intent.hasFileDescriptors() == true) {
11083            throw new IllegalArgumentException("File descriptors passed in Intent");
11084        }
11085
11086        synchronized(this) {
11087            if (!(token instanceof ServiceRecord)) {
11088                throw new IllegalArgumentException("Invalid service token");
11089            }
11090            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11091        }
11092    }
11093
11094    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11095        // Refuse possible leaked file descriptors
11096        if (intent != null && intent.hasFileDescriptors() == true) {
11097            throw new IllegalArgumentException("File descriptors passed in Intent");
11098        }
11099
11100        synchronized(this) {
11101            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11102        }
11103    }
11104
11105    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11106        synchronized(this) {
11107            if (!(token instanceof ServiceRecord)) {
11108                throw new IllegalArgumentException("Invalid service token");
11109            }
11110            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11111        }
11112    }
11113
11114    // =========================================================
11115    // BACKUP AND RESTORE
11116    // =========================================================
11117
11118    // Cause the target app to be launched if necessary and its backup agent
11119    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11120    // activity manager to announce its creation.
11121    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11122        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11123        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11124
11125        synchronized(this) {
11126            // !!! TODO: currently no check here that we're already bound
11127            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11128            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11129            synchronized (stats) {
11130                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11131            }
11132
11133            // Backup agent is now in use, its package can't be stopped.
11134            try {
11135                AppGlobals.getPackageManager().setPackageStoppedState(
11136                        app.packageName, false, UserHandle.getUserId(app.uid));
11137            } catch (RemoteException e) {
11138            } catch (IllegalArgumentException e) {
11139                Slog.w(TAG, "Failed trying to unstop package "
11140                        + app.packageName + ": " + e);
11141            }
11142
11143            BackupRecord r = new BackupRecord(ss, app, backupMode);
11144            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11145                    ? new ComponentName(app.packageName, app.backupAgentName)
11146                    : new ComponentName("android", "FullBackupAgent");
11147            // startProcessLocked() returns existing proc's record if it's already running
11148            ProcessRecord proc = startProcessLocked(app.processName, app,
11149                    false, 0, "backup", hostingName, false, false);
11150            if (proc == null) {
11151                Slog.e(TAG, "Unable to start backup agent process " + r);
11152                return false;
11153            }
11154
11155            r.app = proc;
11156            mBackupTarget = r;
11157            mBackupAppName = app.packageName;
11158
11159            // Try not to kill the process during backup
11160            updateOomAdjLocked(proc);
11161
11162            // If the process is already attached, schedule the creation of the backup agent now.
11163            // If it is not yet live, this will be done when it attaches to the framework.
11164            if (proc.thread != null) {
11165                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11166                try {
11167                    proc.thread.scheduleCreateBackupAgent(app,
11168                            compatibilityInfoForPackageLocked(app), backupMode);
11169                } catch (RemoteException e) {
11170                    // Will time out on the backup manager side
11171                }
11172            } else {
11173                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11174            }
11175            // Invariants: at this point, the target app process exists and the application
11176            // is either already running or in the process of coming up.  mBackupTarget and
11177            // mBackupAppName describe the app, so that when it binds back to the AM we
11178            // know that it's scheduled for a backup-agent operation.
11179        }
11180
11181        return true;
11182    }
11183
11184    @Override
11185    public void clearPendingBackup() {
11186        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11187        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11188
11189        synchronized (this) {
11190            mBackupTarget = null;
11191            mBackupAppName = null;
11192        }
11193    }
11194
11195    // A backup agent has just come up
11196    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11197        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11198                + " = " + agent);
11199
11200        synchronized(this) {
11201            if (!agentPackageName.equals(mBackupAppName)) {
11202                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11203                return;
11204            }
11205        }
11206
11207        long oldIdent = Binder.clearCallingIdentity();
11208        try {
11209            IBackupManager bm = IBackupManager.Stub.asInterface(
11210                    ServiceManager.getService(Context.BACKUP_SERVICE));
11211            bm.agentConnected(agentPackageName, agent);
11212        } catch (RemoteException e) {
11213            // can't happen; the backup manager service is local
11214        } catch (Exception e) {
11215            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11216            e.printStackTrace();
11217        } finally {
11218            Binder.restoreCallingIdentity(oldIdent);
11219        }
11220    }
11221
11222    // done with this agent
11223    public void unbindBackupAgent(ApplicationInfo appInfo) {
11224        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11225        if (appInfo == null) {
11226            Slog.w(TAG, "unbind backup agent for null app");
11227            return;
11228        }
11229
11230        synchronized(this) {
11231            try {
11232                if (mBackupAppName == null) {
11233                    Slog.w(TAG, "Unbinding backup agent with no active backup");
11234                    return;
11235                }
11236
11237                if (!mBackupAppName.equals(appInfo.packageName)) {
11238                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11239                    return;
11240                }
11241
11242                // Not backing this app up any more; reset its OOM adjustment
11243                final ProcessRecord proc = mBackupTarget.app;
11244                updateOomAdjLocked(proc);
11245
11246                // If the app crashed during backup, 'thread' will be null here
11247                if (proc.thread != null) {
11248                    try {
11249                        proc.thread.scheduleDestroyBackupAgent(appInfo,
11250                                compatibilityInfoForPackageLocked(appInfo));
11251                    } catch (Exception e) {
11252                        Slog.e(TAG, "Exception when unbinding backup agent:");
11253                        e.printStackTrace();
11254                    }
11255                }
11256            } finally {
11257                mBackupTarget = null;
11258                mBackupAppName = null;
11259            }
11260        }
11261    }
11262    // =========================================================
11263    // BROADCASTS
11264    // =========================================================
11265
11266    private final List getStickiesLocked(String action, IntentFilter filter,
11267            List cur, int userId) {
11268        final ContentResolver resolver = mContext.getContentResolver();
11269        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11270        if (stickies == null) {
11271            return cur;
11272        }
11273        final ArrayList<Intent> list = stickies.get(action);
11274        if (list == null) {
11275            return cur;
11276        }
11277        int N = list.size();
11278        for (int i=0; i<N; i++) {
11279            Intent intent = list.get(i);
11280            if (filter.match(resolver, intent, true, TAG) >= 0) {
11281                if (cur == null) {
11282                    cur = new ArrayList<Intent>();
11283                }
11284                cur.add(intent);
11285            }
11286        }
11287        return cur;
11288    }
11289
11290    boolean isPendingBroadcastProcessLocked(int pid) {
11291        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11292                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11293    }
11294
11295    void skipPendingBroadcastLocked(int pid) {
11296            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11297            for (BroadcastQueue queue : mBroadcastQueues) {
11298                queue.skipPendingBroadcastLocked(pid);
11299            }
11300    }
11301
11302    // The app just attached; send any pending broadcasts that it should receive
11303    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11304        boolean didSomething = false;
11305        for (BroadcastQueue queue : mBroadcastQueues) {
11306            didSomething |= queue.sendPendingBroadcastsLocked(app);
11307        }
11308        return didSomething;
11309    }
11310
11311    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11312            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11313        enforceNotIsolatedCaller("registerReceiver");
11314        int callingUid;
11315        int callingPid;
11316        synchronized(this) {
11317            ProcessRecord callerApp = null;
11318            if (caller != null) {
11319                callerApp = getRecordForAppLocked(caller);
11320                if (callerApp == null) {
11321                    throw new SecurityException(
11322                            "Unable to find app for caller " + caller
11323                            + " (pid=" + Binder.getCallingPid()
11324                            + ") when registering receiver " + receiver);
11325                }
11326                if (callerApp.info.uid != Process.SYSTEM_UID &&
11327                        !callerApp.pkgList.contains(callerPackage)) {
11328                    throw new SecurityException("Given caller package " + callerPackage
11329                            + " is not running in process " + callerApp);
11330                }
11331                callingUid = callerApp.info.uid;
11332                callingPid = callerApp.pid;
11333            } else {
11334                callerPackage = null;
11335                callingUid = Binder.getCallingUid();
11336                callingPid = Binder.getCallingPid();
11337            }
11338
11339            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11340                    true, true, "registerReceiver", callerPackage);
11341
11342            List allSticky = null;
11343
11344            // Look for any matching sticky broadcasts...
11345            Iterator actions = filter.actionsIterator();
11346            if (actions != null) {
11347                while (actions.hasNext()) {
11348                    String action = (String)actions.next();
11349                    allSticky = getStickiesLocked(action, filter, allSticky,
11350                            UserHandle.USER_ALL);
11351                    allSticky = getStickiesLocked(action, filter, allSticky,
11352                            UserHandle.getUserId(callingUid));
11353                }
11354            } else {
11355                allSticky = getStickiesLocked(null, filter, allSticky,
11356                        UserHandle.USER_ALL);
11357                allSticky = getStickiesLocked(null, filter, allSticky,
11358                        UserHandle.getUserId(callingUid));
11359            }
11360
11361            // The first sticky in the list is returned directly back to
11362            // the client.
11363            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11364
11365            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11366                    + ": " + sticky);
11367
11368            if (receiver == null) {
11369                return sticky;
11370            }
11371
11372            ReceiverList rl
11373                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11374            if (rl == null) {
11375                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11376                        userId, receiver);
11377                if (rl.app != null) {
11378                    rl.app.receivers.add(rl);
11379                } else {
11380                    try {
11381                        receiver.asBinder().linkToDeath(rl, 0);
11382                    } catch (RemoteException e) {
11383                        return sticky;
11384                    }
11385                    rl.linkedToDeath = true;
11386                }
11387                mRegisteredReceivers.put(receiver.asBinder(), rl);
11388            } else if (rl.uid != callingUid) {
11389                throw new IllegalArgumentException(
11390                        "Receiver requested to register for uid " + callingUid
11391                        + " was previously registered for uid " + rl.uid);
11392            } else if (rl.pid != callingPid) {
11393                throw new IllegalArgumentException(
11394                        "Receiver requested to register for pid " + callingPid
11395                        + " was previously registered for pid " + rl.pid);
11396            } else if (rl.userId != userId) {
11397                throw new IllegalArgumentException(
11398                        "Receiver requested to register for user " + userId
11399                        + " was previously registered for user " + rl.userId);
11400            }
11401            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11402                    permission, callingUid, userId);
11403            rl.add(bf);
11404            if (!bf.debugCheck()) {
11405                Slog.w(TAG, "==> For Dynamic broadast");
11406            }
11407            mReceiverResolver.addFilter(bf);
11408
11409            // Enqueue broadcasts for all existing stickies that match
11410            // this filter.
11411            if (allSticky != null) {
11412                ArrayList receivers = new ArrayList();
11413                receivers.add(bf);
11414
11415                int N = allSticky.size();
11416                for (int i=0; i<N; i++) {
11417                    Intent intent = (Intent)allSticky.get(i);
11418                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11419                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11420                            null, -1, -1, null, receivers, null, 0, null, null,
11421                            false, true, true, -1);
11422                    queue.enqueueParallelBroadcastLocked(r);
11423                    queue.scheduleBroadcastsLocked();
11424                }
11425            }
11426
11427            return sticky;
11428        }
11429    }
11430
11431    public void unregisterReceiver(IIntentReceiver receiver) {
11432        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11433
11434        final long origId = Binder.clearCallingIdentity();
11435        try {
11436            boolean doTrim = false;
11437
11438            synchronized(this) {
11439                ReceiverList rl
11440                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11441                if (rl != null) {
11442                    if (rl.curBroadcast != null) {
11443                        BroadcastRecord r = rl.curBroadcast;
11444                        final boolean doNext = finishReceiverLocked(
11445                                receiver.asBinder(), r.resultCode, r.resultData,
11446                                r.resultExtras, r.resultAbort, true);
11447                        if (doNext) {
11448                            doTrim = true;
11449                            r.queue.processNextBroadcast(false);
11450                        }
11451                    }
11452
11453                    if (rl.app != null) {
11454                        rl.app.receivers.remove(rl);
11455                    }
11456                    removeReceiverLocked(rl);
11457                    if (rl.linkedToDeath) {
11458                        rl.linkedToDeath = false;
11459                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11460                    }
11461                }
11462            }
11463
11464            // If we actually concluded any broadcasts, we might now be able
11465            // to trim the recipients' apps from our working set
11466            if (doTrim) {
11467                trimApplications();
11468                return;
11469            }
11470
11471        } finally {
11472            Binder.restoreCallingIdentity(origId);
11473        }
11474    }
11475
11476    void removeReceiverLocked(ReceiverList rl) {
11477        mRegisteredReceivers.remove(rl.receiver.asBinder());
11478        int N = rl.size();
11479        for (int i=0; i<N; i++) {
11480            mReceiverResolver.removeFilter(rl.get(i));
11481        }
11482    }
11483
11484    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11485        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11486            ProcessRecord r = mLruProcesses.get(i);
11487            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11488                try {
11489                    r.thread.dispatchPackageBroadcast(cmd, packages);
11490                } catch (RemoteException ex) {
11491                }
11492            }
11493        }
11494    }
11495
11496    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11497            int[] users) {
11498        List<ResolveInfo> receivers = null;
11499        try {
11500            HashSet<ComponentName> singleUserReceivers = null;
11501            boolean scannedFirstReceivers = false;
11502            for (int user : users) {
11503                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11504                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11505                if (user != 0 && newReceivers != null) {
11506                    // If this is not the primary user, we need to check for
11507                    // any receivers that should be filtered out.
11508                    for (int i=0; i<newReceivers.size(); i++) {
11509                        ResolveInfo ri = newReceivers.get(i);
11510                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11511                            newReceivers.remove(i);
11512                            i--;
11513                        }
11514                    }
11515                }
11516                if (newReceivers != null && newReceivers.size() == 0) {
11517                    newReceivers = null;
11518                }
11519                if (receivers == null) {
11520                    receivers = newReceivers;
11521                } else if (newReceivers != null) {
11522                    // We need to concatenate the additional receivers
11523                    // found with what we have do far.  This would be easy,
11524                    // but we also need to de-dup any receivers that are
11525                    // singleUser.
11526                    if (!scannedFirstReceivers) {
11527                        // Collect any single user receivers we had already retrieved.
11528                        scannedFirstReceivers = true;
11529                        for (int i=0; i<receivers.size(); i++) {
11530                            ResolveInfo ri = receivers.get(i);
11531                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11532                                ComponentName cn = new ComponentName(
11533                                        ri.activityInfo.packageName, ri.activityInfo.name);
11534                                if (singleUserReceivers == null) {
11535                                    singleUserReceivers = new HashSet<ComponentName>();
11536                                }
11537                                singleUserReceivers.add(cn);
11538                            }
11539                        }
11540                    }
11541                    // Add the new results to the existing results, tracking
11542                    // and de-dupping single user receivers.
11543                    for (int i=0; i<newReceivers.size(); i++) {
11544                        ResolveInfo ri = newReceivers.get(i);
11545                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11546                            ComponentName cn = new ComponentName(
11547                                    ri.activityInfo.packageName, ri.activityInfo.name);
11548                            if (singleUserReceivers == null) {
11549                                singleUserReceivers = new HashSet<ComponentName>();
11550                            }
11551                            if (!singleUserReceivers.contains(cn)) {
11552                                singleUserReceivers.add(cn);
11553                                receivers.add(ri);
11554                            }
11555                        } else {
11556                            receivers.add(ri);
11557                        }
11558                    }
11559                }
11560            }
11561        } catch (RemoteException ex) {
11562            // pm is in same process, this will never happen.
11563        }
11564        return receivers;
11565    }
11566
11567    private final int broadcastIntentLocked(ProcessRecord callerApp,
11568            String callerPackage, Intent intent, String resolvedType,
11569            IIntentReceiver resultTo, int resultCode, String resultData,
11570            Bundle map, String requiredPermission,
11571            boolean ordered, boolean sticky, int callingPid, int callingUid,
11572            int userId) {
11573        intent = new Intent(intent);
11574
11575        // By default broadcasts do not go to stopped apps.
11576        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11577
11578        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11579            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11580            + " ordered=" + ordered + " userid=" + userId);
11581        if ((resultTo != null) && !ordered) {
11582            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11583        }
11584
11585        userId = handleIncomingUser(callingPid, callingUid, userId,
11586                true, false, "broadcast", callerPackage);
11587
11588        // Make sure that the user who is receiving this broadcast is started.
11589        // If not, we will just skip it.
11590        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11591            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11592                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11593                Slog.w(TAG, "Skipping broadcast of " + intent
11594                        + ": user " + userId + " is stopped");
11595                return ActivityManager.BROADCAST_SUCCESS;
11596            }
11597        }
11598
11599        /*
11600         * Prevent non-system code (defined here to be non-persistent
11601         * processes) from sending protected broadcasts.
11602         */
11603        int callingAppId = UserHandle.getAppId(callingUid);
11604        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11605            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11606            callingUid == 0) {
11607            // Always okay.
11608        } else if (callerApp == null || !callerApp.persistent) {
11609            try {
11610                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11611                        intent.getAction())) {
11612                    String msg = "Permission Denial: not allowed to send broadcast "
11613                            + intent.getAction() + " from pid="
11614                            + callingPid + ", uid=" + callingUid;
11615                    Slog.w(TAG, msg);
11616                    throw new SecurityException(msg);
11617                }
11618            } catch (RemoteException e) {
11619                Slog.w(TAG, "Remote exception", e);
11620                return ActivityManager.BROADCAST_SUCCESS;
11621            }
11622        }
11623
11624        // Handle special intents: if this broadcast is from the package
11625        // manager about a package being removed, we need to remove all of
11626        // its activities from the history stack.
11627        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11628                intent.getAction());
11629        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11630                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11631                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11632                || uidRemoved) {
11633            if (checkComponentPermission(
11634                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11635                    callingPid, callingUid, -1, true)
11636                    == PackageManager.PERMISSION_GRANTED) {
11637                if (uidRemoved) {
11638                    final Bundle intentExtras = intent.getExtras();
11639                    final int uid = intentExtras != null
11640                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11641                    if (uid >= 0) {
11642                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11643                        synchronized (bs) {
11644                            bs.removeUidStatsLocked(uid);
11645                        }
11646                    }
11647                } else {
11648                    // If resources are unavailable just force stop all
11649                    // those packages and flush the attribute cache as well.
11650                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11651                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11652                        if (list != null && (list.length > 0)) {
11653                            for (String pkg : list) {
11654                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11655                            }
11656                            sendPackageBroadcastLocked(
11657                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11658                        }
11659                    } else {
11660                        Uri data = intent.getData();
11661                        String ssp;
11662                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11663                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11664                                forceStopPackageLocked(ssp,
11665                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11666                                        false, userId);
11667                            }
11668                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11669                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11670                                        new String[] {ssp}, userId);
11671                            }
11672                        }
11673                    }
11674                }
11675            } else {
11676                String msg = "Permission Denial: " + intent.getAction()
11677                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11678                        + ", uid=" + callingUid + ")"
11679                        + " requires "
11680                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11681                Slog.w(TAG, msg);
11682                throw new SecurityException(msg);
11683            }
11684
11685        // Special case for adding a package: by default turn on compatibility
11686        // mode.
11687        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11688            Uri data = intent.getData();
11689            String ssp;
11690            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11691                mCompatModePackages.handlePackageAddedLocked(ssp,
11692                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11693            }
11694        }
11695
11696        /*
11697         * If this is the time zone changed action, queue up a message that will reset the timezone
11698         * of all currently running processes. This message will get queued up before the broadcast
11699         * happens.
11700         */
11701        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11702            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11703        }
11704
11705        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11706            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11707        }
11708
11709        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11710            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11711            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11712        }
11713
11714        // Add to the sticky list if requested.
11715        if (sticky) {
11716            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11717                    callingPid, callingUid)
11718                    != PackageManager.PERMISSION_GRANTED) {
11719                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11720                        + callingPid + ", uid=" + callingUid
11721                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11722                Slog.w(TAG, msg);
11723                throw new SecurityException(msg);
11724            }
11725            if (requiredPermission != null) {
11726                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11727                        + " and enforce permission " + requiredPermission);
11728                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11729            }
11730            if (intent.getComponent() != null) {
11731                throw new SecurityException(
11732                        "Sticky broadcasts can't target a specific component");
11733            }
11734            // We use userId directly here, since the "all" target is maintained
11735            // as a separate set of sticky broadcasts.
11736            if (userId != UserHandle.USER_ALL) {
11737                // But first, if this is not a broadcast to all users, then
11738                // make sure it doesn't conflict with an existing broadcast to
11739                // all users.
11740                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11741                        UserHandle.USER_ALL);
11742                if (stickies != null) {
11743                    ArrayList<Intent> list = stickies.get(intent.getAction());
11744                    if (list != null) {
11745                        int N = list.size();
11746                        int i;
11747                        for (i=0; i<N; i++) {
11748                            if (intent.filterEquals(list.get(i))) {
11749                                throw new IllegalArgumentException(
11750                                        "Sticky broadcast " + intent + " for user "
11751                                        + userId + " conflicts with existing global broadcast");
11752                            }
11753                        }
11754                    }
11755                }
11756            }
11757            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11758            if (stickies == null) {
11759                stickies = new HashMap<String, ArrayList<Intent>>();
11760                mStickyBroadcasts.put(userId, stickies);
11761            }
11762            ArrayList<Intent> list = stickies.get(intent.getAction());
11763            if (list == null) {
11764                list = new ArrayList<Intent>();
11765                stickies.put(intent.getAction(), list);
11766            }
11767            int N = list.size();
11768            int i;
11769            for (i=0; i<N; i++) {
11770                if (intent.filterEquals(list.get(i))) {
11771                    // This sticky already exists, replace it.
11772                    list.set(i, new Intent(intent));
11773                    break;
11774                }
11775            }
11776            if (i >= N) {
11777                list.add(new Intent(intent));
11778            }
11779        }
11780
11781        int[] users;
11782        if (userId == UserHandle.USER_ALL) {
11783            // Caller wants broadcast to go to all started users.
11784            users = mStartedUserArray;
11785        } else {
11786            // Caller wants broadcast to go to one specific user.
11787            users = new int[] {userId};
11788        }
11789
11790        // Figure out who all will receive this broadcast.
11791        List receivers = null;
11792        List<BroadcastFilter> registeredReceivers = null;
11793        // Need to resolve the intent to interested receivers...
11794        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11795                 == 0) {
11796            receivers = collectReceiverComponents(intent, resolvedType, users);
11797        }
11798        if (intent.getComponent() == null) {
11799            registeredReceivers = mReceiverResolver.queryIntent(intent,
11800                    resolvedType, false, userId);
11801        }
11802
11803        final boolean replacePending =
11804                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11805
11806        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11807                + " replacePending=" + replacePending);
11808
11809        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11810        if (!ordered && NR > 0) {
11811            // If we are not serializing this broadcast, then send the
11812            // registered receivers separately so they don't wait for the
11813            // components to be launched.
11814            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11815            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11816                    callerPackage, callingPid, callingUid, requiredPermission,
11817                    registeredReceivers, resultTo, resultCode, resultData, map,
11818                    ordered, sticky, false, userId);
11819            if (DEBUG_BROADCAST) Slog.v(
11820                    TAG, "Enqueueing parallel broadcast " + r);
11821            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11822            if (!replaced) {
11823                queue.enqueueParallelBroadcastLocked(r);
11824                queue.scheduleBroadcastsLocked();
11825            }
11826            registeredReceivers = null;
11827            NR = 0;
11828        }
11829
11830        // Merge into one list.
11831        int ir = 0;
11832        if (receivers != null) {
11833            // A special case for PACKAGE_ADDED: do not allow the package
11834            // being added to see this broadcast.  This prevents them from
11835            // using this as a back door to get run as soon as they are
11836            // installed.  Maybe in the future we want to have a special install
11837            // broadcast or such for apps, but we'd like to deliberately make
11838            // this decision.
11839            String skipPackages[] = null;
11840            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11841                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11842                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11843                Uri data = intent.getData();
11844                if (data != null) {
11845                    String pkgName = data.getSchemeSpecificPart();
11846                    if (pkgName != null) {
11847                        skipPackages = new String[] { pkgName };
11848                    }
11849                }
11850            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11851                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11852            }
11853            if (skipPackages != null && (skipPackages.length > 0)) {
11854                for (String skipPackage : skipPackages) {
11855                    if (skipPackage != null) {
11856                        int NT = receivers.size();
11857                        for (int it=0; it<NT; it++) {
11858                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11859                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11860                                receivers.remove(it);
11861                                it--;
11862                                NT--;
11863                            }
11864                        }
11865                    }
11866                }
11867            }
11868
11869            int NT = receivers != null ? receivers.size() : 0;
11870            int it = 0;
11871            ResolveInfo curt = null;
11872            BroadcastFilter curr = null;
11873            while (it < NT && ir < NR) {
11874                if (curt == null) {
11875                    curt = (ResolveInfo)receivers.get(it);
11876                }
11877                if (curr == null) {
11878                    curr = registeredReceivers.get(ir);
11879                }
11880                if (curr.getPriority() >= curt.priority) {
11881                    // Insert this broadcast record into the final list.
11882                    receivers.add(it, curr);
11883                    ir++;
11884                    curr = null;
11885                    it++;
11886                    NT++;
11887                } else {
11888                    // Skip to the next ResolveInfo in the final list.
11889                    it++;
11890                    curt = null;
11891                }
11892            }
11893        }
11894        while (ir < NR) {
11895            if (receivers == null) {
11896                receivers = new ArrayList();
11897            }
11898            receivers.add(registeredReceivers.get(ir));
11899            ir++;
11900        }
11901
11902        if ((receivers != null && receivers.size() > 0)
11903                || resultTo != null) {
11904            BroadcastQueue queue = broadcastQueueForIntent(intent);
11905            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11906                    callerPackage, callingPid, callingUid, requiredPermission,
11907                    receivers, resultTo, resultCode, resultData, map, ordered,
11908                    sticky, false, userId);
11909            if (DEBUG_BROADCAST) Slog.v(
11910                    TAG, "Enqueueing ordered broadcast " + r
11911                    + ": prev had " + queue.mOrderedBroadcasts.size());
11912            if (DEBUG_BROADCAST) {
11913                int seq = r.intent.getIntExtra("seq", -1);
11914                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11915            }
11916            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11917            if (!replaced) {
11918                queue.enqueueOrderedBroadcastLocked(r);
11919                queue.scheduleBroadcastsLocked();
11920            }
11921        }
11922
11923        return ActivityManager.BROADCAST_SUCCESS;
11924    }
11925
11926    final Intent verifyBroadcastLocked(Intent intent) {
11927        // Refuse possible leaked file descriptors
11928        if (intent != null && intent.hasFileDescriptors() == true) {
11929            throw new IllegalArgumentException("File descriptors passed in Intent");
11930        }
11931
11932        int flags = intent.getFlags();
11933
11934        if (!mProcessesReady) {
11935            // if the caller really truly claims to know what they're doing, go
11936            // ahead and allow the broadcast without launching any receivers
11937            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11938                intent = new Intent(intent);
11939                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11940            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11941                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11942                        + " before boot completion");
11943                throw new IllegalStateException("Cannot broadcast before boot completed");
11944            }
11945        }
11946
11947        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11948            throw new IllegalArgumentException(
11949                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11950        }
11951
11952        return intent;
11953    }
11954
11955    public final int broadcastIntent(IApplicationThread caller,
11956            Intent intent, String resolvedType, IIntentReceiver resultTo,
11957            int resultCode, String resultData, Bundle map,
11958            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11959        enforceNotIsolatedCaller("broadcastIntent");
11960        synchronized(this) {
11961            intent = verifyBroadcastLocked(intent);
11962
11963            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11964            final int callingPid = Binder.getCallingPid();
11965            final int callingUid = Binder.getCallingUid();
11966            final long origId = Binder.clearCallingIdentity();
11967            int res = broadcastIntentLocked(callerApp,
11968                    callerApp != null ? callerApp.info.packageName : null,
11969                    intent, resolvedType, resultTo,
11970                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11971                    callingPid, callingUid, userId);
11972            Binder.restoreCallingIdentity(origId);
11973            return res;
11974        }
11975    }
11976
11977    int broadcastIntentInPackage(String packageName, int uid,
11978            Intent intent, String resolvedType, IIntentReceiver resultTo,
11979            int resultCode, String resultData, Bundle map,
11980            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11981        synchronized(this) {
11982            intent = verifyBroadcastLocked(intent);
11983
11984            final long origId = Binder.clearCallingIdentity();
11985            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11986                    resultTo, resultCode, resultData, map, requiredPermission,
11987                    serialized, sticky, -1, uid, userId);
11988            Binder.restoreCallingIdentity(origId);
11989            return res;
11990        }
11991    }
11992
11993    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11994        // Refuse possible leaked file descriptors
11995        if (intent != null && intent.hasFileDescriptors() == true) {
11996            throw new IllegalArgumentException("File descriptors passed in Intent");
11997        }
11998
11999        userId = handleIncomingUser(Binder.getCallingPid(),
12000                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12001
12002        synchronized(this) {
12003            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12004                    != PackageManager.PERMISSION_GRANTED) {
12005                String msg = "Permission Denial: unbroadcastIntent() from pid="
12006                        + Binder.getCallingPid()
12007                        + ", uid=" + Binder.getCallingUid()
12008                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12009                Slog.w(TAG, msg);
12010                throw new SecurityException(msg);
12011            }
12012            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12013            if (stickies != null) {
12014                ArrayList<Intent> list = stickies.get(intent.getAction());
12015                if (list != null) {
12016                    int N = list.size();
12017                    int i;
12018                    for (i=0; i<N; i++) {
12019                        if (intent.filterEquals(list.get(i))) {
12020                            list.remove(i);
12021                            break;
12022                        }
12023                    }
12024                    if (list.size() <= 0) {
12025                        stickies.remove(intent.getAction());
12026                    }
12027                }
12028                if (stickies.size() <= 0) {
12029                    mStickyBroadcasts.remove(userId);
12030                }
12031            }
12032        }
12033    }
12034
12035    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12036            String resultData, Bundle resultExtras, boolean resultAbort,
12037            boolean explicit) {
12038        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12039        if (r == null) {
12040            Slog.w(TAG, "finishReceiver called but not found on queue");
12041            return false;
12042        }
12043
12044        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12045                explicit);
12046    }
12047
12048    public void finishReceiver(IBinder who, int resultCode, String resultData,
12049            Bundle resultExtras, boolean resultAbort) {
12050        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12051
12052        // Refuse possible leaked file descriptors
12053        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12054            throw new IllegalArgumentException("File descriptors passed in Bundle");
12055        }
12056
12057        final long origId = Binder.clearCallingIdentity();
12058        try {
12059            boolean doNext = false;
12060            BroadcastRecord r = null;
12061
12062            synchronized(this) {
12063                r = broadcastRecordForReceiverLocked(who);
12064                if (r != null) {
12065                    doNext = r.queue.finishReceiverLocked(r, resultCode,
12066                        resultData, resultExtras, resultAbort, true);
12067                }
12068            }
12069
12070            if (doNext) {
12071                r.queue.processNextBroadcast(false);
12072            }
12073            trimApplications();
12074        } finally {
12075            Binder.restoreCallingIdentity(origId);
12076        }
12077    }
12078
12079    // =========================================================
12080    // INSTRUMENTATION
12081    // =========================================================
12082
12083    public boolean startInstrumentation(ComponentName className,
12084            String profileFile, int flags, Bundle arguments,
12085            IInstrumentationWatcher watcher, int userId) {
12086        enforceNotIsolatedCaller("startInstrumentation");
12087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12088                userId, false, true, "startInstrumentation", null);
12089        // Refuse possible leaked file descriptors
12090        if (arguments != null && arguments.hasFileDescriptors()) {
12091            throw new IllegalArgumentException("File descriptors passed in Bundle");
12092        }
12093
12094        synchronized(this) {
12095            InstrumentationInfo ii = null;
12096            ApplicationInfo ai = null;
12097            try {
12098                ii = mContext.getPackageManager().getInstrumentationInfo(
12099                    className, STOCK_PM_FLAGS);
12100                ai = AppGlobals.getPackageManager().getApplicationInfo(
12101                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12102            } catch (PackageManager.NameNotFoundException e) {
12103            } catch (RemoteException e) {
12104            }
12105            if (ii == null) {
12106                reportStartInstrumentationFailure(watcher, className,
12107                        "Unable to find instrumentation info for: " + className);
12108                return false;
12109            }
12110            if (ai == null) {
12111                reportStartInstrumentationFailure(watcher, className,
12112                        "Unable to find instrumentation target package: " + ii.targetPackage);
12113                return false;
12114            }
12115
12116            int match = mContext.getPackageManager().checkSignatures(
12117                    ii.targetPackage, ii.packageName);
12118            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12119                String msg = "Permission Denial: starting instrumentation "
12120                        + className + " from pid="
12121                        + Binder.getCallingPid()
12122                        + ", uid=" + Binder.getCallingPid()
12123                        + " not allowed because package " + ii.packageName
12124                        + " does not have a signature matching the target "
12125                        + ii.targetPackage;
12126                reportStartInstrumentationFailure(watcher, className, msg);
12127                throw new SecurityException(msg);
12128            }
12129
12130            final long origId = Binder.clearCallingIdentity();
12131            // Instrumentation can kill and relaunch even persistent processes
12132            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12133            ProcessRecord app = addAppLocked(ai, false);
12134            app.instrumentationClass = className;
12135            app.instrumentationInfo = ai;
12136            app.instrumentationProfileFile = profileFile;
12137            app.instrumentationArguments = arguments;
12138            app.instrumentationWatcher = watcher;
12139            app.instrumentationResultClass = className;
12140            Binder.restoreCallingIdentity(origId);
12141        }
12142
12143        return true;
12144    }
12145
12146    /**
12147     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12148     * error to the logs, but if somebody is watching, send the report there too.  This enables
12149     * the "am" command to report errors with more information.
12150     *
12151     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12152     * @param cn The component name of the instrumentation.
12153     * @param report The error report.
12154     */
12155    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12156            ComponentName cn, String report) {
12157        Slog.w(TAG, report);
12158        try {
12159            if (watcher != null) {
12160                Bundle results = new Bundle();
12161                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12162                results.putString("Error", report);
12163                watcher.instrumentationStatus(cn, -1, results);
12164            }
12165        } catch (RemoteException e) {
12166            Slog.w(TAG, e);
12167        }
12168    }
12169
12170    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12171        if (app.instrumentationWatcher != null) {
12172            try {
12173                // NOTE:  IInstrumentationWatcher *must* be oneway here
12174                app.instrumentationWatcher.instrumentationFinished(
12175                    app.instrumentationClass,
12176                    resultCode,
12177                    results);
12178            } catch (RemoteException e) {
12179            }
12180        }
12181        app.instrumentationWatcher = null;
12182        app.instrumentationClass = null;
12183        app.instrumentationInfo = null;
12184        app.instrumentationProfileFile = null;
12185        app.instrumentationArguments = null;
12186
12187        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12188    }
12189
12190    public void finishInstrumentation(IApplicationThread target,
12191            int resultCode, Bundle results) {
12192        int userId = UserHandle.getCallingUserId();
12193        // Refuse possible leaked file descriptors
12194        if (results != null && results.hasFileDescriptors()) {
12195            throw new IllegalArgumentException("File descriptors passed in Intent");
12196        }
12197
12198        synchronized(this) {
12199            ProcessRecord app = getRecordForAppLocked(target);
12200            if (app == null) {
12201                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12202                return;
12203            }
12204            final long origId = Binder.clearCallingIdentity();
12205            finishInstrumentationLocked(app, resultCode, results);
12206            Binder.restoreCallingIdentity(origId);
12207        }
12208    }
12209
12210    // =========================================================
12211    // CONFIGURATION
12212    // =========================================================
12213
12214    public ConfigurationInfo getDeviceConfigurationInfo() {
12215        ConfigurationInfo config = new ConfigurationInfo();
12216        synchronized (this) {
12217            config.reqTouchScreen = mConfiguration.touchscreen;
12218            config.reqKeyboardType = mConfiguration.keyboard;
12219            config.reqNavigation = mConfiguration.navigation;
12220            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12221                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12222                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12223            }
12224            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12225                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12226                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12227            }
12228            config.reqGlEsVersion = GL_ES_VERSION;
12229        }
12230        return config;
12231    }
12232
12233    public Configuration getConfiguration() {
12234        Configuration ci;
12235        synchronized(this) {
12236            ci = new Configuration(mConfiguration);
12237        }
12238        return ci;
12239    }
12240
12241    public void updatePersistentConfiguration(Configuration values) {
12242        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12243                "updateConfiguration()");
12244        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12245                "updateConfiguration()");
12246        if (values == null) {
12247            throw new NullPointerException("Configuration must not be null");
12248        }
12249
12250        synchronized(this) {
12251            final long origId = Binder.clearCallingIdentity();
12252            updateConfigurationLocked(values, null, true, false);
12253            Binder.restoreCallingIdentity(origId);
12254        }
12255    }
12256
12257    public void updateConfiguration(Configuration values) {
12258        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12259                "updateConfiguration()");
12260
12261        synchronized(this) {
12262            if (values == null && mWindowManager != null) {
12263                // sentinel: fetch the current configuration from the window manager
12264                values = mWindowManager.computeNewConfiguration();
12265            }
12266
12267            if (mWindowManager != null) {
12268                mProcessList.applyDisplaySize(mWindowManager);
12269            }
12270
12271            final long origId = Binder.clearCallingIdentity();
12272            if (values != null) {
12273                Settings.System.clearConfiguration(values);
12274            }
12275            updateConfigurationLocked(values, null, false, false);
12276            Binder.restoreCallingIdentity(origId);
12277        }
12278    }
12279
12280    /**
12281     * Do either or both things: (1) change the current configuration, and (2)
12282     * make sure the given activity is running with the (now) current
12283     * configuration.  Returns true if the activity has been left running, or
12284     * false if <var>starting</var> is being destroyed to match the new
12285     * configuration.
12286     * @param persistent TODO
12287     */
12288    boolean updateConfigurationLocked(Configuration values,
12289            ActivityRecord starting, boolean persistent, boolean initLocale) {
12290        // do nothing if we are headless
12291        if (mHeadless) return true;
12292
12293        int changes = 0;
12294
12295        boolean kept = true;
12296
12297        if (values != null) {
12298            Configuration newConfig = new Configuration(mConfiguration);
12299            changes = newConfig.updateFrom(values);
12300            if (changes != 0) {
12301                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12302                    Slog.i(TAG, "Updating configuration to: " + values);
12303                }
12304
12305                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12306
12307                if (values.locale != null && !initLocale) {
12308                    saveLocaleLocked(values.locale,
12309                                     !values.locale.equals(mConfiguration.locale),
12310                                     values.userSetLocale);
12311                }
12312
12313                mConfigurationSeq++;
12314                if (mConfigurationSeq <= 0) {
12315                    mConfigurationSeq = 1;
12316                }
12317                newConfig.seq = mConfigurationSeq;
12318                mConfiguration = newConfig;
12319                Slog.i(TAG, "Config changed: " + newConfig);
12320
12321                final Configuration configCopy = new Configuration(mConfiguration);
12322
12323                // TODO: If our config changes, should we auto dismiss any currently
12324                // showing dialogs?
12325                mShowDialogs = shouldShowDialogs(newConfig);
12326
12327                AttributeCache ac = AttributeCache.instance();
12328                if (ac != null) {
12329                    ac.updateConfiguration(configCopy);
12330                }
12331
12332                // Make sure all resources in our process are updated
12333                // right now, so that anyone who is going to retrieve
12334                // resource values after we return will be sure to get
12335                // the new ones.  This is especially important during
12336                // boot, where the first config change needs to guarantee
12337                // all resources have that config before following boot
12338                // code is executed.
12339                mSystemThread.applyConfigurationToResources(configCopy);
12340
12341                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12342                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12343                    msg.obj = new Configuration(configCopy);
12344                    mHandler.sendMessage(msg);
12345                }
12346
12347                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12348                    ProcessRecord app = mLruProcesses.get(i);
12349                    try {
12350                        if (app.thread != null) {
12351                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12352                                    + app.processName + " new config " + mConfiguration);
12353                            app.thread.scheduleConfigurationChanged(configCopy);
12354                        }
12355                    } catch (Exception e) {
12356                    }
12357                }
12358                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12359                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12360                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12361                        | Intent.FLAG_RECEIVER_FOREGROUND);
12362                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12363                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12364                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12365                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12366                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12367                    broadcastIntentLocked(null, null, intent,
12368                            null, null, 0, null, null,
12369                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12370                }
12371            }
12372        }
12373
12374        if (changes != 0 && starting == null) {
12375            // If the configuration changed, and the caller is not already
12376            // in the process of starting an activity, then find the top
12377            // activity to check if its configuration needs to change.
12378            starting = mMainStack.topRunningActivityLocked(null);
12379        }
12380
12381        if (starting != null) {
12382            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12383            // And we need to make sure at this point that all other activities
12384            // are made visible with the correct configuration.
12385            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12386        }
12387
12388        if (values != null && mWindowManager != null) {
12389            mWindowManager.setNewConfiguration(mConfiguration);
12390        }
12391
12392        return kept;
12393    }
12394
12395    /**
12396     * Decide based on the configuration whether we should shouw the ANR,
12397     * crash, etc dialogs.  The idea is that if there is no affordnace to
12398     * press the on-screen buttons, we shouldn't show the dialog.
12399     *
12400     * A thought: SystemUI might also want to get told about this, the Power
12401     * dialog / global actions also might want different behaviors.
12402     */
12403    private static final boolean shouldShowDialogs(Configuration config) {
12404        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12405                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12406    }
12407
12408    /**
12409     * Save the locale.  You must be inside a synchronized (this) block.
12410     */
12411    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12412        if(isDiff) {
12413            SystemProperties.set("user.language", l.getLanguage());
12414            SystemProperties.set("user.region", l.getCountry());
12415        }
12416
12417        if(isPersist) {
12418            SystemProperties.set("persist.sys.language", l.getLanguage());
12419            SystemProperties.set("persist.sys.country", l.getCountry());
12420            SystemProperties.set("persist.sys.localevar", l.getVariant());
12421        }
12422    }
12423
12424    @Override
12425    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12426        ActivityRecord srec = ActivityRecord.forToken(token);
12427        return srec != null && srec.task.affinity != null &&
12428                srec.task.affinity.equals(destAffinity);
12429    }
12430
12431    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12432            Intent resultData) {
12433        ComponentName dest = destIntent.getComponent();
12434
12435        synchronized (this) {
12436            ActivityRecord srec = ActivityRecord.forToken(token);
12437            if (srec == null) {
12438                return false;
12439            }
12440            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12441            final int start = history.indexOf(srec);
12442            if (start < 0) {
12443                // Current activity is not in history stack; do nothing.
12444                return false;
12445            }
12446            int finishTo = start - 1;
12447            ActivityRecord parent = null;
12448            boolean foundParentInTask = false;
12449            if (dest != null) {
12450                TaskRecord tr = srec.task;
12451                for (int i = start - 1; i >= 0; i--) {
12452                    ActivityRecord r = history.get(i);
12453                    if (tr != r.task) {
12454                        // Couldn't find parent in the same task; stop at the one above this.
12455                        // (Root of current task; in-app "home" behavior)
12456                        // Always at least finish the current activity.
12457                        finishTo = Math.min(start - 1, i + 1);
12458                        parent = history.get(finishTo);
12459                        break;
12460                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12461                            r.info.name.equals(dest.getClassName())) {
12462                        finishTo = i;
12463                        parent = r;
12464                        foundParentInTask = true;
12465                        break;
12466                    }
12467                }
12468            }
12469
12470            if (mController != null) {
12471                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12472                if (next != null) {
12473                    // ask watcher if this is allowed
12474                    boolean resumeOK = true;
12475                    try {
12476                        resumeOK = mController.activityResuming(next.packageName);
12477                    } catch (RemoteException e) {
12478                        mController = null;
12479                    }
12480
12481                    if (!resumeOK) {
12482                        return false;
12483                    }
12484                }
12485            }
12486            final long origId = Binder.clearCallingIdentity();
12487            for (int i = start; i > finishTo; i--) {
12488                ActivityRecord r = history.get(i);
12489                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12490                        "navigate-up", true);
12491                // Only return the supplied result for the first activity finished
12492                resultCode = Activity.RESULT_CANCELED;
12493                resultData = null;
12494            }
12495
12496            if (parent != null && foundParentInTask) {
12497                final int parentLaunchMode = parent.info.launchMode;
12498                final int destIntentFlags = destIntent.getFlags();
12499                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12500                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12501                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12502                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12503                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12504                } else {
12505                    try {
12506                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12507                                destIntent.getComponent(), 0, srec.userId);
12508                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12509                                null, aInfo, parent.appToken, null,
12510                                0, -1, parent.launchedFromUid, 0, null, true, null);
12511                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12512                    } catch (RemoteException e) {
12513                        foundParentInTask = false;
12514                    }
12515                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12516                            resultData, "navigate-up", true);
12517                }
12518            }
12519            Binder.restoreCallingIdentity(origId);
12520            return foundParentInTask;
12521        }
12522    }
12523
12524    public int getLaunchedFromUid(IBinder activityToken) {
12525        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12526        if (srec == null) {
12527            return -1;
12528        }
12529        return srec.launchedFromUid;
12530    }
12531
12532    // =========================================================
12533    // LIFETIME MANAGEMENT
12534    // =========================================================
12535
12536    // Returns which broadcast queue the app is the current [or imminent] receiver
12537    // on, or 'null' if the app is not an active broadcast recipient.
12538    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12539        BroadcastRecord r = app.curReceiver;
12540        if (r != null) {
12541            return r.queue;
12542        }
12543
12544        // It's not the current receiver, but it might be starting up to become one
12545        synchronized (this) {
12546            for (BroadcastQueue queue : mBroadcastQueues) {
12547                r = queue.mPendingBroadcast;
12548                if (r != null && r.curApp == app) {
12549                    // found it; report which queue it's in
12550                    return queue;
12551                }
12552            }
12553        }
12554
12555        return null;
12556    }
12557
12558    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12559            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12560        if (mAdjSeq == app.adjSeq) {
12561            // This adjustment has already been computed.  If we are calling
12562            // from the top, we may have already computed our adjustment with
12563            // an earlier hidden adjustment that isn't really for us... if
12564            // so, use the new hidden adjustment.
12565            if (!recursed && app.hidden) {
12566                if (app.hasActivities) {
12567                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12568                } else if (app.hasClientActivities) {
12569                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12570                } else {
12571                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12572                }
12573            }
12574            return app.curRawAdj;
12575        }
12576
12577        if (app.thread == null) {
12578            app.adjSeq = mAdjSeq;
12579            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12580            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12581        }
12582
12583        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12584        app.adjSource = null;
12585        app.adjTarget = null;
12586        app.empty = false;
12587        app.hidden = false;
12588        app.hasClientActivities = false;
12589
12590        final int activitiesSize = app.activities.size();
12591
12592        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12593            // The max adjustment doesn't allow this app to be anything
12594            // below foreground, so it is not worth doing work for it.
12595            app.adjType = "fixed";
12596            app.adjSeq = mAdjSeq;
12597            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12598            app.hasActivities = false;
12599            app.foregroundActivities = false;
12600            app.keeping = true;
12601            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12602            // System process can do UI, and when they do we want to have
12603            // them trim their memory after the user leaves the UI.  To
12604            // facilitate this, here we need to determine whether or not it
12605            // is currently showing UI.
12606            app.systemNoUi = true;
12607            if (app == TOP_APP) {
12608                app.systemNoUi = false;
12609                app.hasActivities = true;
12610            } else if (activitiesSize > 0) {
12611                for (int j = 0; j < activitiesSize; j++) {
12612                    final ActivityRecord r = app.activities.get(j);
12613                    if (r.visible) {
12614                        app.systemNoUi = false;
12615                    }
12616                    if (r.app == app) {
12617                        app.hasActivities = true;
12618                    }
12619                }
12620            }
12621            return (app.curAdj=app.maxAdj);
12622        }
12623
12624        app.keeping = false;
12625        app.systemNoUi = false;
12626        app.hasActivities = false;
12627
12628        // Determine the importance of the process, starting with most
12629        // important to least, and assign an appropriate OOM adjustment.
12630        int adj;
12631        int schedGroup;
12632        boolean foregroundActivities = false;
12633        boolean interesting = false;
12634        BroadcastQueue queue;
12635        if (app == TOP_APP) {
12636            // The last app on the list is the foreground app.
12637            adj = ProcessList.FOREGROUND_APP_ADJ;
12638            schedGroup = Process.THREAD_GROUP_DEFAULT;
12639            app.adjType = "top-activity";
12640            foregroundActivities = true;
12641            interesting = true;
12642            app.hasActivities = true;
12643        } else if (app.instrumentationClass != null) {
12644            // Don't want to kill running instrumentation.
12645            adj = ProcessList.FOREGROUND_APP_ADJ;
12646            schedGroup = Process.THREAD_GROUP_DEFAULT;
12647            app.adjType = "instrumentation";
12648            interesting = true;
12649        } else if ((queue = isReceivingBroadcast(app)) != null) {
12650            // An app that is currently receiving a broadcast also
12651            // counts as being in the foreground for OOM killer purposes.
12652            // It's placed in a sched group based on the nature of the
12653            // broadcast as reflected by which queue it's active in.
12654            adj = ProcessList.FOREGROUND_APP_ADJ;
12655            schedGroup = (queue == mFgBroadcastQueue)
12656                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12657            app.adjType = "broadcast";
12658        } else if (app.executingServices.size() > 0) {
12659            // An app that is currently executing a service callback also
12660            // counts as being in the foreground.
12661            adj = ProcessList.FOREGROUND_APP_ADJ;
12662            schedGroup = Process.THREAD_GROUP_DEFAULT;
12663            app.adjType = "exec-service";
12664        } else {
12665            // Assume process is hidden (has activities); we will correct
12666            // later if this is not the case.
12667            adj = hiddenAdj;
12668            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12669            app.hidden = true;
12670            app.adjType = "bg-act";
12671        }
12672
12673        boolean hasStoppingActivities = false;
12674
12675        // Examine all activities if not already foreground.
12676        if (!foregroundActivities && activitiesSize > 0) {
12677            for (int j = 0; j < activitiesSize; j++) {
12678                final ActivityRecord r = app.activities.get(j);
12679                if (r.visible) {
12680                    // App has a visible activity; only upgrade adjustment.
12681                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12682                        adj = ProcessList.VISIBLE_APP_ADJ;
12683                        app.adjType = "visible";
12684                    }
12685                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12686                    app.hidden = false;
12687                    app.hasActivities = true;
12688                    foregroundActivities = true;
12689                    break;
12690                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12691                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12692                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12693                        app.adjType = "pausing";
12694                    }
12695                    app.hidden = false;
12696                    foregroundActivities = true;
12697                } else if (r.state == ActivityState.STOPPING) {
12698                    // We will apply the actual adjustment later, because
12699                    // we want to allow this process to immediately go through
12700                    // any memory trimming that is in effect.
12701                    app.hidden = false;
12702                    foregroundActivities = true;
12703                    hasStoppingActivities = true;
12704                }
12705                if (r.app == app) {
12706                    app.hasActivities = true;
12707                }
12708            }
12709        }
12710
12711        if (adj == hiddenAdj && !app.hasActivities) {
12712            if (app.hasClientActivities) {
12713                adj = clientHiddenAdj;
12714                app.adjType = "bg-client-act";
12715            } else {
12716                // Whoops, this process is completely empty as far as we know
12717                // at this point.
12718                adj = emptyAdj;
12719                app.empty = true;
12720                app.adjType = "bg-empty";
12721            }
12722        }
12723
12724        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12725            if (app.foregroundServices) {
12726                // The user is aware of this app, so make it visible.
12727                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12728                app.hidden = false;
12729                app.adjType = "fg-service";
12730                schedGroup = Process.THREAD_GROUP_DEFAULT;
12731            } else if (app.forcingToForeground != null) {
12732                // The user is aware of this app, so make it visible.
12733                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12734                app.hidden = false;
12735                app.adjType = "force-fg";
12736                app.adjSource = app.forcingToForeground;
12737                schedGroup = Process.THREAD_GROUP_DEFAULT;
12738            }
12739        }
12740
12741        if (app.foregroundServices) {
12742            interesting = true;
12743        }
12744
12745        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12746            // We don't want to kill the current heavy-weight process.
12747            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12748            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12749            app.hidden = false;
12750            app.adjType = "heavy";
12751        }
12752
12753        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12754            // This process is hosting what we currently consider to be the
12755            // home app, so we don't want to let it go into the background.
12756            adj = ProcessList.HOME_APP_ADJ;
12757            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12758            app.hidden = false;
12759            app.adjType = "home";
12760        }
12761
12762        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12763                && app.activities.size() > 0) {
12764            // This was the previous process that showed UI to the user.
12765            // We want to try to keep it around more aggressively, to give
12766            // a good experience around switching between two apps.
12767            adj = ProcessList.PREVIOUS_APP_ADJ;
12768            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12769            app.hidden = false;
12770            app.adjType = "previous";
12771        }
12772
12773        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12774                + " reason=" + app.adjType);
12775
12776        // By default, we use the computed adjustment.  It may be changed if
12777        // there are applications dependent on our services or providers, but
12778        // this gives us a baseline and makes sure we don't get into an
12779        // infinite recursion.
12780        app.adjSeq = mAdjSeq;
12781        app.curRawAdj = app.nonStoppingAdj = adj;
12782
12783        if (mBackupTarget != null && app == mBackupTarget.app) {
12784            // If possible we want to avoid killing apps while they're being backed up
12785            if (adj > ProcessList.BACKUP_APP_ADJ) {
12786                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12787                adj = ProcessList.BACKUP_APP_ADJ;
12788                app.adjType = "backup";
12789                app.hidden = false;
12790            }
12791        }
12792
12793        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12794                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12795            final long now = SystemClock.uptimeMillis();
12796            // This process is more important if the top activity is
12797            // bound to the service.
12798            Iterator<ServiceRecord> jt = app.services.iterator();
12799            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12800                ServiceRecord s = jt.next();
12801                if (s.startRequested) {
12802                    if (app.hasShownUi && app != mHomeProcess) {
12803                        // If this process has shown some UI, let it immediately
12804                        // go to the LRU list because it may be pretty heavy with
12805                        // UI stuff.  We'll tag it with a label just to help
12806                        // debug and understand what is going on.
12807                        if (adj > ProcessList.SERVICE_ADJ) {
12808                            app.adjType = "started-bg-ui-services";
12809                        }
12810                    } else {
12811                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12812                            // This service has seen some activity within
12813                            // recent memory, so we will keep its process ahead
12814                            // of the background processes.
12815                            if (adj > ProcessList.SERVICE_ADJ) {
12816                                adj = ProcessList.SERVICE_ADJ;
12817                                app.adjType = "started-services";
12818                                app.hidden = false;
12819                            }
12820                        }
12821                        // If we have let the service slide into the background
12822                        // state, still have some text describing what it is doing
12823                        // even though the service no longer has an impact.
12824                        if (adj > ProcessList.SERVICE_ADJ) {
12825                            app.adjType = "started-bg-services";
12826                        }
12827                    }
12828                    // Don't kill this process because it is doing work; it
12829                    // has said it is doing work.
12830                    app.keeping = true;
12831                }
12832                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12833                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12834                    Iterator<ArrayList<ConnectionRecord>> kt
12835                            = s.connections.values().iterator();
12836                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12837                        ArrayList<ConnectionRecord> clist = kt.next();
12838                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12839                            // XXX should compute this based on the max of
12840                            // all connected clients.
12841                            ConnectionRecord cr = clist.get(i);
12842                            if (cr.binding.client == app) {
12843                                // Binding to ourself is not interesting.
12844                                continue;
12845                            }
12846                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12847                                ProcessRecord client = cr.binding.client;
12848                                int clientAdj = adj;
12849                                int myHiddenAdj = hiddenAdj;
12850                                if (myHiddenAdj > client.hiddenAdj) {
12851                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12852                                        myHiddenAdj = client.hiddenAdj;
12853                                    } else {
12854                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12855                                    }
12856                                }
12857                                int myClientHiddenAdj = clientHiddenAdj;
12858                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12859                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12860                                        myClientHiddenAdj = client.clientHiddenAdj;
12861                                    } else {
12862                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12863                                    }
12864                                }
12865                                int myEmptyAdj = emptyAdj;
12866                                if (myEmptyAdj > client.emptyAdj) {
12867                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12868                                        myEmptyAdj = client.emptyAdj;
12869                                    } else {
12870                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12871                                    }
12872                                }
12873                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12874                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12875                                String adjType = null;
12876                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12877                                    // Not doing bind OOM management, so treat
12878                                    // this guy more like a started service.
12879                                    if (app.hasShownUi && app != mHomeProcess) {
12880                                        // If this process has shown some UI, let it immediately
12881                                        // go to the LRU list because it may be pretty heavy with
12882                                        // UI stuff.  We'll tag it with a label just to help
12883                                        // debug and understand what is going on.
12884                                        if (adj > clientAdj) {
12885                                            adjType = "bound-bg-ui-services";
12886                                        }
12887                                        app.hidden = false;
12888                                        clientAdj = adj;
12889                                    } else {
12890                                        if (now >= (s.lastActivity
12891                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12892                                            // This service has not seen activity within
12893                                            // recent memory, so allow it to drop to the
12894                                            // LRU list if there is no other reason to keep
12895                                            // it around.  We'll also tag it with a label just
12896                                            // to help debug and undertand what is going on.
12897                                            if (adj > clientAdj) {
12898                                                adjType = "bound-bg-services";
12899                                            }
12900                                            clientAdj = adj;
12901                                        }
12902                                    }
12903                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12904                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12905                                        // If this connection is keeping the service
12906                                        // created, then we want to try to better follow
12907                                        // its memory management semantics for activities.
12908                                        // That is, if it is sitting in the background
12909                                        // LRU list as a hidden process (with activities),
12910                                        // we don't want the service it is connected to
12911                                        // to go into the empty LRU and quickly get killed,
12912                                        // because I'll we'll do is just end up restarting
12913                                        // the service.
12914                                        app.hasClientActivities |= client.hasActivities;
12915                                    }
12916                                }
12917                                if (adj > clientAdj) {
12918                                    // If this process has recently shown UI, and
12919                                    // the process that is binding to it is less
12920                                    // important than being visible, then we don't
12921                                    // care about the binding as much as we care
12922                                    // about letting this process get into the LRU
12923                                    // list to be killed and restarted if needed for
12924                                    // memory.
12925                                    if (app.hasShownUi && app != mHomeProcess
12926                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12927                                        adjType = "bound-bg-ui-services";
12928                                    } else {
12929                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12930                                                |Context.BIND_IMPORTANT)) != 0) {
12931                                            adj = clientAdj;
12932                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12933                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12934                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12935                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12936                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12937                                            adj = clientAdj;
12938                                        } else {
12939                                            app.pendingUiClean = true;
12940                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12941                                                adj = ProcessList.VISIBLE_APP_ADJ;
12942                                            }
12943                                        }
12944                                        if (!client.hidden) {
12945                                            app.hidden = false;
12946                                        }
12947                                        if (client.keeping) {
12948                                            app.keeping = true;
12949                                        }
12950                                        adjType = "service";
12951                                    }
12952                                }
12953                                if (adjType != null) {
12954                                    app.adjType = adjType;
12955                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12956                                            .REASON_SERVICE_IN_USE;
12957                                    app.adjSource = cr.binding.client;
12958                                    app.adjSourceOom = clientAdj;
12959                                    app.adjTarget = s.name;
12960                                }
12961                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12962                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12963                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12964                                    }
12965                                }
12966                            }
12967                            final ActivityRecord a = cr.activity;
12968                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12969                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12970                                        (a.visible || a.state == ActivityState.RESUMED
12971                                         || a.state == ActivityState.PAUSING)) {
12972                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12973                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12974                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12975                                    }
12976                                    app.hidden = false;
12977                                    app.adjType = "service";
12978                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12979                                            .REASON_SERVICE_IN_USE;
12980                                    app.adjSource = a;
12981                                    app.adjSourceOom = adj;
12982                                    app.adjTarget = s.name;
12983                                }
12984                            }
12985                        }
12986                    }
12987                }
12988            }
12989
12990            // Finally, if this process has active services running in it, we
12991            // would like to avoid killing it unless it would prevent the current
12992            // application from running.  By default we put the process in
12993            // with the rest of the background processes; as we scan through
12994            // its services we may bump it up from there.
12995            if (adj > hiddenAdj) {
12996                adj = hiddenAdj;
12997                app.hidden = false;
12998                app.adjType = "bg-services";
12999            }
13000        }
13001
13002        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13003                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13004            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13005            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13006                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13007                ContentProviderRecord cpr = jt.next();
13008                for (int i = cpr.connections.size()-1;
13009                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13010                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13011                        i--) {
13012                    ContentProviderConnection conn = cpr.connections.get(i);
13013                    ProcessRecord client = conn.client;
13014                    if (client == app) {
13015                        // Being our own client is not interesting.
13016                        continue;
13017                    }
13018                    int myHiddenAdj = hiddenAdj;
13019                    if (myHiddenAdj > client.hiddenAdj) {
13020                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13021                            myHiddenAdj = client.hiddenAdj;
13022                        } else {
13023                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13024                        }
13025                    }
13026                    int myClientHiddenAdj = clientHiddenAdj;
13027                    if (myClientHiddenAdj > client.clientHiddenAdj) {
13028                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13029                            myClientHiddenAdj = client.clientHiddenAdj;
13030                        } else {
13031                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13032                        }
13033                    }
13034                    int myEmptyAdj = emptyAdj;
13035                    if (myEmptyAdj > client.emptyAdj) {
13036                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13037                            myEmptyAdj = client.emptyAdj;
13038                        } else {
13039                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13040                        }
13041                    }
13042                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13043                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13044                    if (adj > clientAdj) {
13045                        if (app.hasShownUi && app != mHomeProcess
13046                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13047                            app.adjType = "bg-ui-provider";
13048                        } else {
13049                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13050                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13051                            app.adjType = "provider";
13052                        }
13053                        if (!client.hidden) {
13054                            app.hidden = false;
13055                        }
13056                        if (client.keeping) {
13057                            app.keeping = true;
13058                        }
13059                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13060                                .REASON_PROVIDER_IN_USE;
13061                        app.adjSource = client;
13062                        app.adjSourceOom = clientAdj;
13063                        app.adjTarget = cpr.name;
13064                    }
13065                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13066                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13067                    }
13068                }
13069                // If the provider has external (non-framework) process
13070                // dependencies, ensure that its adjustment is at least
13071                // FOREGROUND_APP_ADJ.
13072                if (cpr.hasExternalProcessHandles()) {
13073                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13074                        adj = ProcessList.FOREGROUND_APP_ADJ;
13075                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13076                        app.hidden = false;
13077                        app.keeping = true;
13078                        app.adjType = "provider";
13079                        app.adjTarget = cpr.name;
13080                    }
13081                }
13082            }
13083        }
13084
13085        if (adj == ProcessList.SERVICE_ADJ) {
13086            if (doingAll) {
13087                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13088                mNewNumServiceProcs++;
13089            }
13090            if (app.serviceb) {
13091                adj = ProcessList.SERVICE_B_ADJ;
13092            }
13093        } else {
13094            app.serviceb = false;
13095        }
13096
13097        app.nonStoppingAdj = adj;
13098
13099        if (hasStoppingActivities) {
13100            // Only upgrade adjustment.
13101            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13102                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13103                app.adjType = "stopping";
13104            }
13105        }
13106
13107        app.curRawAdj = adj;
13108
13109        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13110        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13111        if (adj > app.maxAdj) {
13112            adj = app.maxAdj;
13113            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13114                schedGroup = Process.THREAD_GROUP_DEFAULT;
13115            }
13116        }
13117        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13118            app.keeping = true;
13119        }
13120
13121        if (app.hasAboveClient) {
13122            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13123            // then we need to drop its adjustment to be lower than the service's
13124            // in order to honor the request.  We want to drop it by one adjustment
13125            // level...  but there is special meaning applied to various levels so
13126            // we will skip some of them.
13127            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13128                // System process will not get dropped, ever
13129            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13130                adj = ProcessList.VISIBLE_APP_ADJ;
13131            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13132                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13133            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13134                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13135            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13136                adj++;
13137            }
13138        }
13139
13140        int importance = app.memImportance;
13141        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13142            app.curAdj = adj;
13143            app.curSchedGroup = schedGroup;
13144            if (!interesting) {
13145                // For this reporting, if there is not something explicitly
13146                // interesting in this process then we will push it to the
13147                // background importance.
13148                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13149            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13150                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13151            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13152                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13153            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13154                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13155            } else if (adj >= ProcessList.SERVICE_ADJ) {
13156                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13157            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13158                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13159            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13160                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13161            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13162                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13163            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13164                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13165            } else {
13166                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13167            }
13168        }
13169
13170        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13171        if (foregroundActivities != app.foregroundActivities) {
13172            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13173        }
13174        if (changes != 0) {
13175            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13176            app.memImportance = importance;
13177            app.foregroundActivities = foregroundActivities;
13178            int i = mPendingProcessChanges.size()-1;
13179            ProcessChangeItem item = null;
13180            while (i >= 0) {
13181                item = mPendingProcessChanges.get(i);
13182                if (item.pid == app.pid) {
13183                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13184                    break;
13185                }
13186                i--;
13187            }
13188            if (i < 0) {
13189                // No existing item in pending changes; need a new one.
13190                final int NA = mAvailProcessChanges.size();
13191                if (NA > 0) {
13192                    item = mAvailProcessChanges.remove(NA-1);
13193                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13194                } else {
13195                    item = new ProcessChangeItem();
13196                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13197                }
13198                item.changes = 0;
13199                item.pid = app.pid;
13200                item.uid = app.info.uid;
13201                if (mPendingProcessChanges.size() == 0) {
13202                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13203                            "*** Enqueueing dispatch processes changed!");
13204                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13205                }
13206                mPendingProcessChanges.add(item);
13207            }
13208            item.changes |= changes;
13209            item.importance = importance;
13210            item.foregroundActivities = foregroundActivities;
13211            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13212                    + Integer.toHexString(System.identityHashCode(item))
13213                    + " " + app.toShortString() + ": changes=" + item.changes
13214                    + " importance=" + item.importance
13215                    + " foreground=" + item.foregroundActivities
13216                    + " type=" + app.adjType + " source=" + app.adjSource
13217                    + " target=" + app.adjTarget);
13218        }
13219
13220        return app.curRawAdj;
13221    }
13222
13223    /**
13224     * Ask a given process to GC right now.
13225     */
13226    final void performAppGcLocked(ProcessRecord app) {
13227        try {
13228            app.lastRequestedGc = SystemClock.uptimeMillis();
13229            if (app.thread != null) {
13230                if (app.reportLowMemory) {
13231                    app.reportLowMemory = false;
13232                    app.thread.scheduleLowMemory();
13233                } else {
13234                    app.thread.processInBackground();
13235                }
13236            }
13237        } catch (Exception e) {
13238            // whatever.
13239        }
13240    }
13241
13242    /**
13243     * Returns true if things are idle enough to perform GCs.
13244     */
13245    private final boolean canGcNowLocked() {
13246        boolean processingBroadcasts = false;
13247        for (BroadcastQueue q : mBroadcastQueues) {
13248            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13249                processingBroadcasts = true;
13250            }
13251        }
13252        return !processingBroadcasts
13253                && (mSleeping || (mMainStack.mResumedActivity != null &&
13254                        mMainStack.mResumedActivity.idle));
13255    }
13256
13257    /**
13258     * Perform GCs on all processes that are waiting for it, but only
13259     * if things are idle.
13260     */
13261    final void performAppGcsLocked() {
13262        final int N = mProcessesToGc.size();
13263        if (N <= 0) {
13264            return;
13265        }
13266        if (canGcNowLocked()) {
13267            while (mProcessesToGc.size() > 0) {
13268                ProcessRecord proc = mProcessesToGc.remove(0);
13269                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13270                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13271                            <= SystemClock.uptimeMillis()) {
13272                        // To avoid spamming the system, we will GC processes one
13273                        // at a time, waiting a few seconds between each.
13274                        performAppGcLocked(proc);
13275                        scheduleAppGcsLocked();
13276                        return;
13277                    } else {
13278                        // It hasn't been long enough since we last GCed this
13279                        // process...  put it in the list to wait for its time.
13280                        addProcessToGcListLocked(proc);
13281                        break;
13282                    }
13283                }
13284            }
13285
13286            scheduleAppGcsLocked();
13287        }
13288    }
13289
13290    /**
13291     * If all looks good, perform GCs on all processes waiting for them.
13292     */
13293    final void performAppGcsIfAppropriateLocked() {
13294        if (canGcNowLocked()) {
13295            performAppGcsLocked();
13296            return;
13297        }
13298        // Still not idle, wait some more.
13299        scheduleAppGcsLocked();
13300    }
13301
13302    /**
13303     * Schedule the execution of all pending app GCs.
13304     */
13305    final void scheduleAppGcsLocked() {
13306        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13307
13308        if (mProcessesToGc.size() > 0) {
13309            // Schedule a GC for the time to the next process.
13310            ProcessRecord proc = mProcessesToGc.get(0);
13311            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13312
13313            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13314            long now = SystemClock.uptimeMillis();
13315            if (when < (now+GC_TIMEOUT)) {
13316                when = now + GC_TIMEOUT;
13317            }
13318            mHandler.sendMessageAtTime(msg, when);
13319        }
13320    }
13321
13322    /**
13323     * Add a process to the array of processes waiting to be GCed.  Keeps the
13324     * list in sorted order by the last GC time.  The process can't already be
13325     * on the list.
13326     */
13327    final void addProcessToGcListLocked(ProcessRecord proc) {
13328        boolean added = false;
13329        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13330            if (mProcessesToGc.get(i).lastRequestedGc <
13331                    proc.lastRequestedGc) {
13332                added = true;
13333                mProcessesToGc.add(i+1, proc);
13334                break;
13335            }
13336        }
13337        if (!added) {
13338            mProcessesToGc.add(0, proc);
13339        }
13340    }
13341
13342    /**
13343     * Set up to ask a process to GC itself.  This will either do it
13344     * immediately, or put it on the list of processes to gc the next
13345     * time things are idle.
13346     */
13347    final void scheduleAppGcLocked(ProcessRecord app) {
13348        long now = SystemClock.uptimeMillis();
13349        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13350            return;
13351        }
13352        if (!mProcessesToGc.contains(app)) {
13353            addProcessToGcListLocked(app);
13354            scheduleAppGcsLocked();
13355        }
13356    }
13357
13358    final void checkExcessivePowerUsageLocked(boolean doKills) {
13359        updateCpuStatsNow();
13360
13361        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13362        boolean doWakeKills = doKills;
13363        boolean doCpuKills = doKills;
13364        if (mLastPowerCheckRealtime == 0) {
13365            doWakeKills = false;
13366        }
13367        if (mLastPowerCheckUptime == 0) {
13368            doCpuKills = false;
13369        }
13370        if (stats.isScreenOn()) {
13371            doWakeKills = false;
13372        }
13373        final long curRealtime = SystemClock.elapsedRealtime();
13374        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13375        final long curUptime = SystemClock.uptimeMillis();
13376        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13377        mLastPowerCheckRealtime = curRealtime;
13378        mLastPowerCheckUptime = curUptime;
13379        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13380            doWakeKills = false;
13381        }
13382        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13383            doCpuKills = false;
13384        }
13385        int i = mLruProcesses.size();
13386        while (i > 0) {
13387            i--;
13388            ProcessRecord app = mLruProcesses.get(i);
13389            if (!app.keeping) {
13390                long wtime;
13391                synchronized (stats) {
13392                    wtime = stats.getProcessWakeTime(app.info.uid,
13393                            app.pid, curRealtime);
13394                }
13395                long wtimeUsed = wtime - app.lastWakeTime;
13396                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13397                if (DEBUG_POWER) {
13398                    StringBuilder sb = new StringBuilder(128);
13399                    sb.append("Wake for ");
13400                    app.toShortString(sb);
13401                    sb.append(": over ");
13402                    TimeUtils.formatDuration(realtimeSince, sb);
13403                    sb.append(" used ");
13404                    TimeUtils.formatDuration(wtimeUsed, sb);
13405                    sb.append(" (");
13406                    sb.append((wtimeUsed*100)/realtimeSince);
13407                    sb.append("%)");
13408                    Slog.i(TAG, sb.toString());
13409                    sb.setLength(0);
13410                    sb.append("CPU for ");
13411                    app.toShortString(sb);
13412                    sb.append(": over ");
13413                    TimeUtils.formatDuration(uptimeSince, sb);
13414                    sb.append(" used ");
13415                    TimeUtils.formatDuration(cputimeUsed, sb);
13416                    sb.append(" (");
13417                    sb.append((cputimeUsed*100)/uptimeSince);
13418                    sb.append("%)");
13419                    Slog.i(TAG, sb.toString());
13420                }
13421                // If a process has held a wake lock for more
13422                // than 50% of the time during this period,
13423                // that sounds bad.  Kill!
13424                if (doWakeKills && realtimeSince > 0
13425                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13426                    synchronized (stats) {
13427                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13428                                realtimeSince, wtimeUsed);
13429                    }
13430                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13431                            + " (pid " + app.pid + "): held " + wtimeUsed
13432                            + " during " + realtimeSince);
13433                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13434                            app.processName, app.setAdj, "excessive wake lock");
13435                    Process.killProcessQuiet(app.pid);
13436                } else if (doCpuKills && uptimeSince > 0
13437                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13438                    synchronized (stats) {
13439                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13440                                uptimeSince, cputimeUsed);
13441                    }
13442                    Slog.w(TAG, "Excessive CPU in " + app.processName
13443                            + " (pid " + app.pid + "): used " + cputimeUsed
13444                            + " during " + uptimeSince);
13445                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13446                            app.processName, app.setAdj, "excessive cpu");
13447                    Process.killProcessQuiet(app.pid);
13448                } else {
13449                    app.lastWakeTime = wtime;
13450                    app.lastCpuTime = app.curCpuTime;
13451                }
13452            }
13453        }
13454    }
13455
13456    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13457            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13458        app.hiddenAdj = hiddenAdj;
13459        app.clientHiddenAdj = clientHiddenAdj;
13460        app.emptyAdj = emptyAdj;
13461
13462        if (app.thread == null) {
13463            return false;
13464        }
13465
13466        final boolean wasKeeping = app.keeping;
13467
13468        boolean success = true;
13469
13470        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13471
13472        if (app.curRawAdj != app.setRawAdj) {
13473            if (wasKeeping && !app.keeping) {
13474                // This app is no longer something we want to keep.  Note
13475                // its current wake lock time to later know to kill it if
13476                // it is not behaving well.
13477                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13478                synchronized (stats) {
13479                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13480                            app.pid, SystemClock.elapsedRealtime());
13481                }
13482                app.lastCpuTime = app.curCpuTime;
13483            }
13484
13485            app.setRawAdj = app.curRawAdj;
13486        }
13487
13488        if (app.curAdj != app.setAdj) {
13489            if (Process.setOomAdj(app.pid, app.curAdj)) {
13490                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13491                    TAG, "Set " + app.pid + " " + app.processName +
13492                    " adj " + app.curAdj + ": " + app.adjType);
13493                app.setAdj = app.curAdj;
13494            } else {
13495                success = false;
13496                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13497            }
13498        }
13499        if (app.setSchedGroup != app.curSchedGroup) {
13500            app.setSchedGroup = app.curSchedGroup;
13501            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13502                    "Setting process group of " + app.processName
13503                    + " to " + app.curSchedGroup);
13504            if (app.waitingToKill != null &&
13505                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13506                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13507                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13508                        app.processName, app.setAdj, app.waitingToKill);
13509                app.killedBackground = true;
13510                Process.killProcessQuiet(app.pid);
13511                success = false;
13512            } else {
13513                if (true) {
13514                    long oldId = Binder.clearCallingIdentity();
13515                    try {
13516                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13517                    } catch (Exception e) {
13518                        Slog.w(TAG, "Failed setting process group of " + app.pid
13519                                + " to " + app.curSchedGroup);
13520                        e.printStackTrace();
13521                    } finally {
13522                        Binder.restoreCallingIdentity(oldId);
13523                    }
13524                } else {
13525                    if (app.thread != null) {
13526                        try {
13527                            app.thread.setSchedulingGroup(app.curSchedGroup);
13528                        } catch (RemoteException e) {
13529                        }
13530                    }
13531                }
13532            }
13533        }
13534        return success;
13535    }
13536
13537    private final ActivityRecord resumedAppLocked() {
13538        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13539        if (resumedActivity == null || resumedActivity.app == null) {
13540            resumedActivity = mMainStack.mPausingActivity;
13541            if (resumedActivity == null || resumedActivity.app == null) {
13542                resumedActivity = mMainStack.topRunningActivityLocked(null);
13543            }
13544        }
13545        return resumedActivity;
13546    }
13547
13548    final boolean updateOomAdjLocked(ProcessRecord app) {
13549        final ActivityRecord TOP_ACT = resumedAppLocked();
13550        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13551        int curAdj = app.curAdj;
13552        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13553            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13554
13555        mAdjSeq++;
13556
13557        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13558                app.emptyAdj, TOP_APP, false);
13559        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13560            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13561        if (nowHidden != wasHidden) {
13562            // Changed to/from hidden state, so apps after it in the LRU
13563            // list may also be changed.
13564            updateOomAdjLocked();
13565        }
13566        return success;
13567    }
13568
13569    final void updateOomAdjLocked() {
13570        final ActivityRecord TOP_ACT = resumedAppLocked();
13571        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13572        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13573
13574        if (false) {
13575            RuntimeException e = new RuntimeException();
13576            e.fillInStackTrace();
13577            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13578        }
13579
13580        mAdjSeq++;
13581        mNewNumServiceProcs = 0;
13582
13583        final int emptyProcessLimit;
13584        final int hiddenProcessLimit;
13585        if (mProcessLimit <= 0) {
13586            emptyProcessLimit = hiddenProcessLimit = 0;
13587        } else if (mProcessLimit == 1) {
13588            emptyProcessLimit = 1;
13589            hiddenProcessLimit = 0;
13590        } else {
13591            emptyProcessLimit = (mProcessLimit*2)/3;
13592            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13593        }
13594
13595        // Let's determine how many processes we have running vs.
13596        // how many slots we have for background processes; we may want
13597        // to put multiple processes in a slot of there are enough of
13598        // them.
13599        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13600                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13601        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13602        if (numEmptyProcs > hiddenProcessLimit) {
13603            // If there are more empty processes than our limit on hidden
13604            // processes, then use the hidden process limit for the factor.
13605            // This ensures that the really old empty processes get pushed
13606            // down to the bottom, so if we are running low on memory we will
13607            // have a better chance at keeping around more hidden processes
13608            // instead of a gazillion empty processes.
13609            numEmptyProcs = hiddenProcessLimit;
13610        }
13611        int emptyFactor = numEmptyProcs/numSlots;
13612        if (emptyFactor < 1) emptyFactor = 1;
13613        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13614        if (hiddenFactor < 1) hiddenFactor = 1;
13615        int stepHidden = 0;
13616        int stepEmpty = 0;
13617        int numHidden = 0;
13618        int numEmpty = 0;
13619        int numTrimming = 0;
13620
13621        mNumNonHiddenProcs = 0;
13622        mNumHiddenProcs = 0;
13623
13624        // First update the OOM adjustment for each of the
13625        // application processes based on their current state.
13626        int i = mLruProcesses.size();
13627        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13628        int nextHiddenAdj = curHiddenAdj+1;
13629        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13630        int nextEmptyAdj = curEmptyAdj+2;
13631        int curClientHiddenAdj = curEmptyAdj;
13632        while (i > 0) {
13633            i--;
13634            ProcessRecord app = mLruProcesses.get(i);
13635            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13636            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13637            if (!app.killedBackground) {
13638                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13639                    // This process was assigned as a hidden process...  step the
13640                    // hidden level.
13641                    mNumHiddenProcs++;
13642                    if (curHiddenAdj != nextHiddenAdj) {
13643                        stepHidden++;
13644                        if (stepHidden >= hiddenFactor) {
13645                            stepHidden = 0;
13646                            curHiddenAdj = nextHiddenAdj;
13647                            nextHiddenAdj += 2;
13648                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13649                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13650                            }
13651                            if (curClientHiddenAdj <= curHiddenAdj) {
13652                                curClientHiddenAdj = curHiddenAdj + 1;
13653                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13654                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13655                                }
13656                            }
13657                        }
13658                    }
13659                    numHidden++;
13660                    if (numHidden > hiddenProcessLimit) {
13661                        Slog.i(TAG, "No longer want " + app.processName
13662                                + " (pid " + app.pid + "): hidden #" + numHidden);
13663                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13664                                app.processName, app.setAdj, "too many background");
13665                        app.killedBackground = true;
13666                        Process.killProcessQuiet(app.pid);
13667                    }
13668                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13669                    // This process has a client that has activities.  We will have
13670                    // given it the current hidden adj; here we will just leave it
13671                    // without stepping the hidden adj.
13672                    curClientHiddenAdj++;
13673                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13674                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13675                    }
13676                } else {
13677                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13678                        // This process was assigned as an empty process...  step the
13679                        // empty level.
13680                        if (curEmptyAdj != nextEmptyAdj) {
13681                            stepEmpty++;
13682                            if (stepEmpty >= emptyFactor) {
13683                                stepEmpty = 0;
13684                                curEmptyAdj = nextEmptyAdj;
13685                                nextEmptyAdj += 2;
13686                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13687                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13688                                }
13689                            }
13690                        }
13691                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13692                        mNumNonHiddenProcs++;
13693                    }
13694                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13695                            && !app.hasClientActivities) {
13696                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13697                                && app.lastActivityTime < oldTime) {
13698                            Slog.i(TAG, "No longer want " + app.processName
13699                                    + " (pid " + app.pid + "): empty for "
13700                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13701                                            / 1000) + "s");
13702                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13703                                    app.processName, app.setAdj, "old background process");
13704                            app.killedBackground = true;
13705                            Process.killProcessQuiet(app.pid);
13706                        } else {
13707                            numEmpty++;
13708                            if (numEmpty > emptyProcessLimit) {
13709                                Slog.i(TAG, "No longer want " + app.processName
13710                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13711                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13712                                        app.processName, app.setAdj, "too many background");
13713                                app.killedBackground = true;
13714                                Process.killProcessQuiet(app.pid);
13715                            }
13716                        }
13717                    }
13718                }
13719                if (app.isolated && app.services.size() <= 0) {
13720                    // If this is an isolated process, and there are no
13721                    // services running in it, then the process is no longer
13722                    // needed.  We agressively kill these because we can by
13723                    // definition not re-use the same process again, and it is
13724                    // good to avoid having whatever code was running in them
13725                    // left sitting around after no longer needed.
13726                    Slog.i(TAG, "Isolated process " + app.processName
13727                            + " (pid " + app.pid + ") no longer needed");
13728                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13729                            app.processName, app.setAdj, "isolated not needed");
13730                    app.killedBackground = true;
13731                    Process.killProcessQuiet(app.pid);
13732                }
13733                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13734                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13735                        && !app.killedBackground) {
13736                    numTrimming++;
13737                }
13738            }
13739        }
13740
13741        mNumServiceProcs = mNewNumServiceProcs;
13742
13743        // Now determine the memory trimming level of background processes.
13744        // Unfortunately we need to start at the back of the list to do this
13745        // properly.  We only do this if the number of background apps we
13746        // are managing to keep around is less than half the maximum we desire;
13747        // if we are keeping a good number around, we'll let them use whatever
13748        // memory they want.
13749        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13750                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13751            final int numHiddenAndEmpty = numHidden + numEmpty;
13752            final int N = mLruProcesses.size();
13753            int factor = numTrimming/3;
13754            int minFactor = 2;
13755            if (mHomeProcess != null) minFactor++;
13756            if (mPreviousProcess != null) minFactor++;
13757            if (factor < minFactor) factor = minFactor;
13758            int step = 0;
13759            int fgTrimLevel;
13760            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13761                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13762            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13763                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13764            } else {
13765                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13766            }
13767            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13768            for (i=0; i<N; i++) {
13769                ProcessRecord app = mLruProcesses.get(i);
13770                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13771                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13772                        && !app.killedBackground) {
13773                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13774                        try {
13775                            app.thread.scheduleTrimMemory(curLevel);
13776                        } catch (RemoteException e) {
13777                        }
13778                        if (false) {
13779                            // For now we won't do this; our memory trimming seems
13780                            // to be good enough at this point that destroying
13781                            // activities causes more harm than good.
13782                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13783                                    && app != mHomeProcess && app != mPreviousProcess) {
13784                                // Need to do this on its own message because the stack may not
13785                                // be in a consistent state at this point.
13786                                // For these apps we will also finish their activities
13787                                // to help them free memory.
13788                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13789                            }
13790                        }
13791                    }
13792                    app.trimMemoryLevel = curLevel;
13793                    step++;
13794                    if (step >= factor) {
13795                        step = 0;
13796                        switch (curLevel) {
13797                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13798                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13799                                break;
13800                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13801                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13802                                break;
13803                        }
13804                    }
13805                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13806                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13807                            && app.thread != null) {
13808                        try {
13809                            app.thread.scheduleTrimMemory(
13810                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13811                        } catch (RemoteException e) {
13812                        }
13813                    }
13814                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13815                } else {
13816                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13817                            && app.pendingUiClean) {
13818                        // If this application is now in the background and it
13819                        // had done UI, then give it the special trim level to
13820                        // have it free UI resources.
13821                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13822                        if (app.trimMemoryLevel < level && app.thread != null) {
13823                            try {
13824                                app.thread.scheduleTrimMemory(level);
13825                            } catch (RemoteException e) {
13826                            }
13827                        }
13828                        app.pendingUiClean = false;
13829                    }
13830                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13831                        try {
13832                            app.thread.scheduleTrimMemory(fgTrimLevel);
13833                        } catch (RemoteException e) {
13834                        }
13835                    }
13836                    app.trimMemoryLevel = fgTrimLevel;
13837                }
13838            }
13839        } else {
13840            final int N = mLruProcesses.size();
13841            for (i=0; i<N; i++) {
13842                ProcessRecord app = mLruProcesses.get(i);
13843                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13844                        && app.pendingUiClean) {
13845                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13846                            && app.thread != null) {
13847                        try {
13848                            app.thread.scheduleTrimMemory(
13849                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13850                        } catch (RemoteException e) {
13851                        }
13852                    }
13853                    app.pendingUiClean = false;
13854                }
13855                app.trimMemoryLevel = 0;
13856            }
13857        }
13858
13859        if (mAlwaysFinishActivities) {
13860            // Need to do this on its own message because the stack may not
13861            // be in a consistent state at this point.
13862            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13863        }
13864    }
13865
13866    final void trimApplications() {
13867        synchronized (this) {
13868            int i;
13869
13870            // First remove any unused application processes whose package
13871            // has been removed.
13872            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13873                final ProcessRecord app = mRemovedProcesses.get(i);
13874                if (app.activities.size() == 0
13875                        && app.curReceiver == null && app.services.size() == 0) {
13876                    Slog.i(
13877                        TAG, "Exiting empty application process "
13878                        + app.processName + " ("
13879                        + (app.thread != null ? app.thread.asBinder() : null)
13880                        + ")\n");
13881                    if (app.pid > 0 && app.pid != MY_PID) {
13882                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13883                                app.processName, app.setAdj, "empty");
13884                        Process.killProcessQuiet(app.pid);
13885                    } else {
13886                        try {
13887                            app.thread.scheduleExit();
13888                        } catch (Exception e) {
13889                            // Ignore exceptions.
13890                        }
13891                    }
13892                    cleanUpApplicationRecordLocked(app, false, true, -1);
13893                    mRemovedProcesses.remove(i);
13894
13895                    if (app.persistent) {
13896                        if (app.persistent) {
13897                            addAppLocked(app.info, false);
13898                        }
13899                    }
13900                }
13901            }
13902
13903            // Now update the oom adj for all processes.
13904            updateOomAdjLocked();
13905        }
13906    }
13907
13908    /** This method sends the specified signal to each of the persistent apps */
13909    public void signalPersistentProcesses(int sig) throws RemoteException {
13910        if (sig != Process.SIGNAL_USR1) {
13911            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13912        }
13913
13914        synchronized (this) {
13915            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13916                    != PackageManager.PERMISSION_GRANTED) {
13917                throw new SecurityException("Requires permission "
13918                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13919            }
13920
13921            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13922                ProcessRecord r = mLruProcesses.get(i);
13923                if (r.thread != null && r.persistent) {
13924                    Process.sendSignal(r.pid, sig);
13925                }
13926            }
13927        }
13928    }
13929
13930    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13931        if (proc == null || proc == mProfileProc) {
13932            proc = mProfileProc;
13933            path = mProfileFile;
13934            profileType = mProfileType;
13935            clearProfilerLocked();
13936        }
13937        if (proc == null) {
13938            return;
13939        }
13940        try {
13941            proc.thread.profilerControl(false, path, null, profileType);
13942        } catch (RemoteException e) {
13943            throw new IllegalStateException("Process disappeared");
13944        }
13945    }
13946
13947    private void clearProfilerLocked() {
13948        if (mProfileFd != null) {
13949            try {
13950                mProfileFd.close();
13951            } catch (IOException e) {
13952            }
13953        }
13954        mProfileApp = null;
13955        mProfileProc = null;
13956        mProfileFile = null;
13957        mProfileType = 0;
13958        mAutoStopProfiler = false;
13959    }
13960
13961    public boolean profileControl(String process, int userId, boolean start,
13962            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13963
13964        try {
13965            synchronized (this) {
13966                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13967                // its own permission.
13968                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13969                        != PackageManager.PERMISSION_GRANTED) {
13970                    throw new SecurityException("Requires permission "
13971                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13972                }
13973
13974                if (start && fd == null) {
13975                    throw new IllegalArgumentException("null fd");
13976                }
13977
13978                ProcessRecord proc = null;
13979                if (process != null) {
13980                    proc = findProcessLocked(process, userId, "profileControl");
13981                }
13982
13983                if (start && (proc == null || proc.thread == null)) {
13984                    throw new IllegalArgumentException("Unknown process: " + process);
13985                }
13986
13987                if (start) {
13988                    stopProfilerLocked(null, null, 0);
13989                    setProfileApp(proc.info, proc.processName, path, fd, false);
13990                    mProfileProc = proc;
13991                    mProfileType = profileType;
13992                    try {
13993                        fd = fd.dup();
13994                    } catch (IOException e) {
13995                        fd = null;
13996                    }
13997                    proc.thread.profilerControl(start, path, fd, profileType);
13998                    fd = null;
13999                    mProfileFd = null;
14000                } else {
14001                    stopProfilerLocked(proc, path, profileType);
14002                    if (fd != null) {
14003                        try {
14004                            fd.close();
14005                        } catch (IOException e) {
14006                        }
14007                    }
14008                }
14009
14010                return true;
14011            }
14012        } catch (RemoteException e) {
14013            throw new IllegalStateException("Process disappeared");
14014        } finally {
14015            if (fd != null) {
14016                try {
14017                    fd.close();
14018                } catch (IOException e) {
14019                }
14020            }
14021        }
14022    }
14023
14024    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14025        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14026                userId, true, true, callName, null);
14027        ProcessRecord proc = null;
14028        try {
14029            int pid = Integer.parseInt(process);
14030            synchronized (mPidsSelfLocked) {
14031                proc = mPidsSelfLocked.get(pid);
14032            }
14033        } catch (NumberFormatException e) {
14034        }
14035
14036        if (proc == null) {
14037            HashMap<String, SparseArray<ProcessRecord>> all
14038                    = mProcessNames.getMap();
14039            SparseArray<ProcessRecord> procs = all.get(process);
14040            if (procs != null && procs.size() > 0) {
14041                proc = procs.valueAt(0);
14042                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14043                    for (int i=1; i<procs.size(); i++) {
14044                        ProcessRecord thisProc = procs.valueAt(i);
14045                        if (thisProc.userId == userId) {
14046                            proc = thisProc;
14047                            break;
14048                        }
14049                    }
14050                }
14051            }
14052        }
14053
14054        return proc;
14055    }
14056
14057    public boolean dumpHeap(String process, int userId, boolean managed,
14058            String path, ParcelFileDescriptor fd) throws RemoteException {
14059
14060        try {
14061            synchronized (this) {
14062                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14063                // its own permission (same as profileControl).
14064                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14065                        != PackageManager.PERMISSION_GRANTED) {
14066                    throw new SecurityException("Requires permission "
14067                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14068                }
14069
14070                if (fd == null) {
14071                    throw new IllegalArgumentException("null fd");
14072                }
14073
14074                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14075                if (proc == null || proc.thread == null) {
14076                    throw new IllegalArgumentException("Unknown process: " + process);
14077                }
14078
14079                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14080                if (!isDebuggable) {
14081                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14082                        throw new SecurityException("Process not debuggable: " + proc);
14083                    }
14084                }
14085
14086                proc.thread.dumpHeap(managed, path, fd);
14087                fd = null;
14088                return true;
14089            }
14090        } catch (RemoteException e) {
14091            throw new IllegalStateException("Process disappeared");
14092        } finally {
14093            if (fd != null) {
14094                try {
14095                    fd.close();
14096                } catch (IOException e) {
14097                }
14098            }
14099        }
14100    }
14101
14102    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14103    public void monitor() {
14104        synchronized (this) { }
14105    }
14106
14107    void onCoreSettingsChange(Bundle settings) {
14108        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14109            ProcessRecord processRecord = mLruProcesses.get(i);
14110            try {
14111                if (processRecord.thread != null) {
14112                    processRecord.thread.setCoreSettings(settings);
14113                }
14114            } catch (RemoteException re) {
14115                /* ignore */
14116            }
14117        }
14118    }
14119
14120    // Multi-user methods
14121
14122    @Override
14123    public boolean switchUser(int userId) {
14124        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14125                != PackageManager.PERMISSION_GRANTED) {
14126            String msg = "Permission Denial: switchUser() from pid="
14127                    + Binder.getCallingPid()
14128                    + ", uid=" + Binder.getCallingUid()
14129                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14130            Slog.w(TAG, msg);
14131            throw new SecurityException(msg);
14132        }
14133
14134        final long ident = Binder.clearCallingIdentity();
14135        try {
14136            synchronized (this) {
14137                final int oldUserId = mCurrentUserId;
14138                if (oldUserId == userId) {
14139                    return true;
14140                }
14141
14142                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14143                if (userInfo == null) {
14144                    Slog.w(TAG, "No user info for user #" + userId);
14145                    return false;
14146                }
14147
14148                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14149                        R.anim.screen_user_enter);
14150
14151                boolean needStart = false;
14152
14153                // If the user we are switching to is not currently started, then
14154                // we need to start it now.
14155                if (mStartedUsers.get(userId) == null) {
14156                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14157                    updateStartedUserArrayLocked();
14158                    needStart = true;
14159                }
14160
14161                mCurrentUserId = userId;
14162                mCurrentUserArray = new int[] { userId };
14163                final Integer userIdInt = Integer.valueOf(userId);
14164                mUserLru.remove(userIdInt);
14165                mUserLru.add(userIdInt);
14166
14167                mWindowManager.setCurrentUser(userId);
14168
14169                // Once the internal notion of the active user has switched, we lock the device
14170                // with the option to show the user switcher on the keyguard.
14171                mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
14172
14173                final UserStartedState uss = mStartedUsers.get(userId);
14174
14175                // Make sure user is in the started state.  If it is currently
14176                // stopping, we need to knock that off.
14177                if (uss.mState == UserStartedState.STATE_STOPPING) {
14178                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14179                    // so we can just fairly silently bring the user back from
14180                    // the almost-dead.
14181                    uss.mState = UserStartedState.STATE_RUNNING;
14182                    updateStartedUserArrayLocked();
14183                    needStart = true;
14184                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14185                    // This means ACTION_SHUTDOWN has been sent, so we will
14186                    // need to treat this as a new boot of the user.
14187                    uss.mState = UserStartedState.STATE_BOOTING;
14188                    updateStartedUserArrayLocked();
14189                    needStart = true;
14190                }
14191
14192                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14193                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14194                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14195                        oldUserId, userId, uss));
14196                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14197                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14198                if (needStart) {
14199                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14200                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14201                            | Intent.FLAG_RECEIVER_FOREGROUND);
14202                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14203                    broadcastIntentLocked(null, null, intent,
14204                            null, null, 0, null, null, null,
14205                            false, false, MY_PID, Process.SYSTEM_UID, userId);
14206                }
14207
14208                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14209                    if (userId != 0) {
14210                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14211                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14212                        broadcastIntentLocked(null, null, intent, null,
14213                                new IIntentReceiver.Stub() {
14214                                    public void performReceive(Intent intent, int resultCode,
14215                                            String data, Bundle extras, boolean ordered,
14216                                            boolean sticky, int sendingUser) {
14217                                        userInitialized(uss);
14218                                    }
14219                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14220                                userId);
14221                        uss.initializing = true;
14222                    } else {
14223                        getUserManagerLocked().makeInitialized(userInfo.id);
14224                    }
14225                }
14226
14227                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14228                if (!haveActivities) {
14229                    startHomeActivityLocked(userId);
14230                }
14231
14232                getUserManagerLocked().userForeground(userId);
14233                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14234                if (needStart) {
14235                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14236                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14237                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14238                    broadcastIntentLocked(null, null, intent,
14239                            null, new IIntentReceiver.Stub() {
14240                                @Override
14241                                public void performReceive(Intent intent, int resultCode, String data,
14242                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14243                                        throws RemoteException {
14244                                }
14245                            }, 0, null, null,
14246                            android.Manifest.permission.INTERACT_ACROSS_USERS,
14247                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14248                }
14249            }
14250        } finally {
14251            Binder.restoreCallingIdentity(ident);
14252        }
14253
14254        return true;
14255    }
14256
14257    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14258        long ident = Binder.clearCallingIdentity();
14259        try {
14260            Intent intent;
14261            if (oldUserId >= 0) {
14262                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14263                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14264                        | Intent.FLAG_RECEIVER_FOREGROUND);
14265                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14266                broadcastIntentLocked(null, null, intent,
14267                        null, null, 0, null, null, null,
14268                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14269            }
14270            if (newUserId >= 0) {
14271                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14272                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14273                        | Intent.FLAG_RECEIVER_FOREGROUND);
14274                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14275                broadcastIntentLocked(null, null, intent,
14276                        null, null, 0, null, null, null,
14277                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14278                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14279                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14280                        | Intent.FLAG_RECEIVER_FOREGROUND);
14281                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14282                broadcastIntentLocked(null, null, intent,
14283                        null, null, 0, null, null,
14284                        android.Manifest.permission.MANAGE_USERS,
14285                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14286            }
14287        } finally {
14288            Binder.restoreCallingIdentity(ident);
14289        }
14290    }
14291
14292    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14293            final int newUserId) {
14294        final int N = mUserSwitchObservers.beginBroadcast();
14295        if (N > 0) {
14296            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14297                int mCount = 0;
14298                @Override
14299                public void sendResult(Bundle data) throws RemoteException {
14300                    synchronized (ActivityManagerService.this) {
14301                        if (mCurUserSwitchCallback == this) {
14302                            mCount++;
14303                            if (mCount == N) {
14304                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14305                            }
14306                        }
14307                    }
14308                }
14309            };
14310            synchronized (this) {
14311                uss.switching = true;
14312                mCurUserSwitchCallback = callback;
14313            }
14314            for (int i=0; i<N; i++) {
14315                try {
14316                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14317                            newUserId, callback);
14318                } catch (RemoteException e) {
14319                }
14320            }
14321        } else {
14322            synchronized (this) {
14323                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14324            }
14325        }
14326        mUserSwitchObservers.finishBroadcast();
14327    }
14328
14329    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14330        synchronized (this) {
14331            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14332            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14333        }
14334    }
14335
14336    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14337        mCurUserSwitchCallback = null;
14338        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14339        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14340                oldUserId, newUserId, uss));
14341    }
14342
14343    void userInitialized(UserStartedState uss) {
14344        synchronized (ActivityManagerService.this) {
14345            getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14346            uss.initializing = false;
14347            completeSwitchAndInitalizeLocked(uss);
14348        }
14349    }
14350
14351    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14352        final int N = mUserSwitchObservers.beginBroadcast();
14353        for (int i=0; i<N; i++) {
14354            try {
14355                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14356            } catch (RemoteException e) {
14357            }
14358        }
14359        mUserSwitchObservers.finishBroadcast();
14360        synchronized (this) {
14361            uss.switching = false;
14362            completeSwitchAndInitalizeLocked(uss);
14363        }
14364    }
14365
14366    void completeSwitchAndInitalizeLocked(UserStartedState uss) {
14367        if (!uss.switching && !uss.initializing) {
14368            mWindowManager.stopFreezingScreen();
14369        }
14370    }
14371
14372    void finishUserSwitch(UserStartedState uss) {
14373        synchronized (this) {
14374            if (uss.mState == UserStartedState.STATE_BOOTING
14375                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14376                uss.mState = UserStartedState.STATE_RUNNING;
14377                final int userId = uss.mHandle.getIdentifier();
14378                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14379                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14380                broadcastIntentLocked(null, null, intent,
14381                        null, null, 0, null, null,
14382                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14383                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14384            }
14385            int num = mUserLru.size();
14386            int i = 0;
14387            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14388                Integer oldUserId = mUserLru.get(i);
14389                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14390                if (oldUss == null) {
14391                    // Shouldn't happen, but be sane if it does.
14392                    mUserLru.remove(i);
14393                    num--;
14394                    continue;
14395                }
14396                if (oldUss.mState == UserStartedState.STATE_STOPPING
14397                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14398                    // This user is already stopping, doesn't count.
14399                    num--;
14400                    i++;
14401                    continue;
14402                }
14403                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14404                    // Owner and current can't be stopped, but count as running.
14405                    i++;
14406                    continue;
14407                }
14408                // This is a user to be stopped.
14409                stopUserLocked(oldUserId, null);
14410                num--;
14411                i++;
14412            }
14413        }
14414    }
14415
14416    @Override
14417    public int stopUser(final int userId, final IStopUserCallback callback) {
14418        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14419                != PackageManager.PERMISSION_GRANTED) {
14420            String msg = "Permission Denial: switchUser() from pid="
14421                    + Binder.getCallingPid()
14422                    + ", uid=" + Binder.getCallingUid()
14423                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14424            Slog.w(TAG, msg);
14425            throw new SecurityException(msg);
14426        }
14427        if (userId <= 0) {
14428            throw new IllegalArgumentException("Can't stop primary user " + userId);
14429        }
14430        synchronized (this) {
14431            return stopUserLocked(userId, callback);
14432        }
14433    }
14434
14435    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14436        if (mCurrentUserId == userId) {
14437            return ActivityManager.USER_OP_IS_CURRENT;
14438        }
14439
14440        final UserStartedState uss = mStartedUsers.get(userId);
14441        if (uss == null) {
14442            // User is not started, nothing to do...  but we do need to
14443            // callback if requested.
14444            if (callback != null) {
14445                mHandler.post(new Runnable() {
14446                    @Override
14447                    public void run() {
14448                        try {
14449                            callback.userStopped(userId);
14450                        } catch (RemoteException e) {
14451                        }
14452                    }
14453                });
14454            }
14455            return ActivityManager.USER_OP_SUCCESS;
14456        }
14457
14458        if (callback != null) {
14459            uss.mStopCallbacks.add(callback);
14460        }
14461
14462        if (uss.mState != UserStartedState.STATE_STOPPING
14463                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14464            uss.mState = UserStartedState.STATE_STOPPING;
14465            updateStartedUserArrayLocked();
14466
14467            long ident = Binder.clearCallingIdentity();
14468            try {
14469                // We are going to broadcast ACTION_USER_STOPPING and then
14470                // once that is down send a final ACTION_SHUTDOWN and then
14471                // stop the user.
14472                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14473                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14474                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14475                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14476                // This is the result receiver for the final shutdown broadcast.
14477                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14478                    @Override
14479                    public void performReceive(Intent intent, int resultCode, String data,
14480                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14481                        finishUserStop(uss);
14482                    }
14483                };
14484                // This is the result receiver for the initial stopping broadcast.
14485                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14486                    @Override
14487                    public void performReceive(Intent intent, int resultCode, String data,
14488                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14489                        // On to the next.
14490                        synchronized (ActivityManagerService.this) {
14491                            if (uss.mState != UserStartedState.STATE_STOPPING) {
14492                                // Whoops, we are being started back up.  Abort, abort!
14493                                return;
14494                            }
14495                            uss.mState = UserStartedState.STATE_SHUTDOWN;
14496                        }
14497                        broadcastIntentLocked(null, null, shutdownIntent,
14498                                null, shutdownReceiver, 0, null, null, null,
14499                                true, false, MY_PID, Process.SYSTEM_UID, userId);
14500                    }
14501                };
14502                // Kick things off.
14503                broadcastIntentLocked(null, null, stoppingIntent,
14504                        null, stoppingReceiver, 0, null, null,
14505                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14506                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14507            } finally {
14508                Binder.restoreCallingIdentity(ident);
14509            }
14510        }
14511
14512        return ActivityManager.USER_OP_SUCCESS;
14513    }
14514
14515    void finishUserStop(UserStartedState uss) {
14516        final int userId = uss.mHandle.getIdentifier();
14517        boolean stopped;
14518        ArrayList<IStopUserCallback> callbacks;
14519        synchronized (this) {
14520            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14521            if (mStartedUsers.get(userId) != uss) {
14522                stopped = false;
14523            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14524                stopped = false;
14525            } else {
14526                stopped = true;
14527                // User can no longer run.
14528                mStartedUsers.remove(userId);
14529                mUserLru.remove(Integer.valueOf(userId));
14530                updateStartedUserArrayLocked();
14531
14532                // Clean up all state and processes associated with the user.
14533                // Kill all the processes for the user.
14534                forceStopUserLocked(userId);
14535            }
14536        }
14537
14538        for (int i=0; i<callbacks.size(); i++) {
14539            try {
14540                if (stopped) callbacks.get(i).userStopped(userId);
14541                else callbacks.get(i).userStopAborted(userId);
14542            } catch (RemoteException e) {
14543            }
14544        }
14545    }
14546
14547    @Override
14548    public UserInfo getCurrentUser() {
14549        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14550                != PackageManager.PERMISSION_GRANTED) && (
14551                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14552                != PackageManager.PERMISSION_GRANTED)) {
14553            String msg = "Permission Denial: getCurrentUser() from pid="
14554                    + Binder.getCallingPid()
14555                    + ", uid=" + Binder.getCallingUid()
14556                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14557            Slog.w(TAG, msg);
14558            throw new SecurityException(msg);
14559        }
14560        synchronized (this) {
14561            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14562        }
14563    }
14564
14565    int getCurrentUserIdLocked() {
14566        return mCurrentUserId;
14567    }
14568
14569    @Override
14570    public boolean isUserRunning(int userId, boolean orStopped) {
14571        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14572                != PackageManager.PERMISSION_GRANTED) {
14573            String msg = "Permission Denial: isUserRunning() from pid="
14574                    + Binder.getCallingPid()
14575                    + ", uid=" + Binder.getCallingUid()
14576                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14577            Slog.w(TAG, msg);
14578            throw new SecurityException(msg);
14579        }
14580        synchronized (this) {
14581            return isUserRunningLocked(userId, orStopped);
14582        }
14583    }
14584
14585    boolean isUserRunningLocked(int userId, boolean orStopped) {
14586        UserStartedState state = mStartedUsers.get(userId);
14587        if (state == null) {
14588            return false;
14589        }
14590        if (orStopped) {
14591            return true;
14592        }
14593        return state.mState != UserStartedState.STATE_STOPPING
14594                && state.mState != UserStartedState.STATE_SHUTDOWN;
14595    }
14596
14597    @Override
14598    public int[] getRunningUserIds() {
14599        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14600                != PackageManager.PERMISSION_GRANTED) {
14601            String msg = "Permission Denial: isUserRunning() from pid="
14602                    + Binder.getCallingPid()
14603                    + ", uid=" + Binder.getCallingUid()
14604                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14605            Slog.w(TAG, msg);
14606            throw new SecurityException(msg);
14607        }
14608        synchronized (this) {
14609            return mStartedUserArray;
14610        }
14611    }
14612
14613    private void updateStartedUserArrayLocked() {
14614        int num = 0;
14615        for (int i=0; i<mStartedUsers.size();  i++) {
14616            UserStartedState uss = mStartedUsers.valueAt(i);
14617            // This list does not include stopping users.
14618            if (uss.mState != UserStartedState.STATE_STOPPING
14619                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14620                num++;
14621            }
14622        }
14623        mStartedUserArray = new int[num];
14624        num = 0;
14625        for (int i=0; i<mStartedUsers.size();  i++) {
14626            UserStartedState uss = mStartedUsers.valueAt(i);
14627            if (uss.mState != UserStartedState.STATE_STOPPING
14628                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14629                mStartedUserArray[num] = mStartedUsers.keyAt(i);
14630                num++;
14631            }
14632        }
14633    }
14634
14635    @Override
14636    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14637        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14638                != PackageManager.PERMISSION_GRANTED) {
14639            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14640                    + Binder.getCallingPid()
14641                    + ", uid=" + Binder.getCallingUid()
14642                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14643            Slog.w(TAG, msg);
14644            throw new SecurityException(msg);
14645        }
14646
14647        mUserSwitchObservers.register(observer);
14648    }
14649
14650    @Override
14651    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14652        mUserSwitchObservers.unregister(observer);
14653    }
14654
14655    private boolean userExists(int userId) {
14656        if (userId == 0) {
14657            return true;
14658        }
14659        UserManagerService ums = getUserManagerLocked();
14660        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14661    }
14662
14663    int[] getUsersLocked() {
14664        UserManagerService ums = getUserManagerLocked();
14665        return ums != null ? ums.getUserIds() : new int[] { 0 };
14666    }
14667
14668    UserManagerService getUserManagerLocked() {
14669        if (mUserManager == null) {
14670            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14671            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14672        }
14673        return mUserManager;
14674    }
14675
14676    private void checkValidCaller(int uid, int userId) {
14677        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14678
14679        throw new SecurityException("Caller uid=" + uid
14680                + " is not privileged to communicate with user=" + userId);
14681    }
14682
14683    private int applyUserId(int uid, int userId) {
14684        return UserHandle.getUid(userId, uid);
14685    }
14686
14687    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14688        if (info == null) return null;
14689        ApplicationInfo newInfo = new ApplicationInfo(info);
14690        newInfo.uid = applyUserId(info.uid, userId);
14691        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14692                + info.packageName;
14693        return newInfo;
14694    }
14695
14696    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14697        if (aInfo == null
14698                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14699            return aInfo;
14700        }
14701
14702        ActivityInfo info = new ActivityInfo(aInfo);
14703        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14704        return info;
14705    }
14706}
14707