ActivityManagerService.java revision a8a9bd65bf5865d83ef44f54552ca39522bfbcf0
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.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3744        broadcastIntentLocked(null, null, intent,
3745                null, null, 0, null, null, null,
3746                false, false,
3747                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3748    }
3749
3750    private final boolean killPackageProcessesLocked(String packageName, int appId,
3751            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3752            boolean doit, boolean evenPersistent, String reason) {
3753        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3754
3755        // Remove all processes this package may have touched: all with the
3756        // same UID (except for the system or root user), and all whose name
3757        // matches the package name.
3758        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3759        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3760            final int NA = apps.size();
3761            for (int ia=0; ia<NA; ia++) {
3762                ProcessRecord app = apps.valueAt(ia);
3763                if (app.persistent && !evenPersistent) {
3764                    // we don't kill persistent processes
3765                    continue;
3766                }
3767                if (app.removed) {
3768                    if (doit) {
3769                        procs.add(app);
3770                    }
3771                    continue;
3772                }
3773
3774                // Skip process if it doesn't meet our oom adj requirement.
3775                if (app.setAdj < minOomAdj) {
3776                    continue;
3777                }
3778
3779                // If no package is specified, we call all processes under the
3780                // give user id.
3781                if (packageName == null) {
3782                    if (app.userId != userId) {
3783                        continue;
3784                    }
3785                // Package has been specified, we want to hit all processes
3786                // that match it.  We need to qualify this by the processes
3787                // that are running under the specified app and user ID.
3788                } else {
3789                    if (UserHandle.getAppId(app.uid) != appId) {
3790                        continue;
3791                    }
3792                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3793                        continue;
3794                    }
3795                    if (!app.pkgList.contains(packageName)) {
3796                        continue;
3797                    }
3798                }
3799
3800                // Process has passed all conditions, kill it!
3801                if (!doit) {
3802                    return true;
3803                }
3804                app.removed = true;
3805                procs.add(app);
3806            }
3807        }
3808
3809        int N = procs.size();
3810        for (int i=0; i<N; i++) {
3811            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3812        }
3813        return N > 0;
3814    }
3815
3816    private final boolean forceStopPackageLocked(String name, int appId,
3817            boolean callerWillRestart, boolean purgeCache, boolean doit,
3818            boolean evenPersistent, int userId) {
3819        int i;
3820        int N;
3821
3822        if (userId == UserHandle.USER_ALL && name == null) {
3823            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3824        }
3825
3826        if (appId < 0 && name != null) {
3827            try {
3828                appId = UserHandle.getAppId(
3829                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3830            } catch (RemoteException e) {
3831            }
3832        }
3833
3834        if (doit) {
3835            if (name != null) {
3836                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3837                        + " user=" + userId);
3838            } else {
3839                Slog.i(TAG, "Force stopping user " + userId);
3840            }
3841
3842            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3843            while (badApps.hasNext()) {
3844                SparseArray<Long> ba = badApps.next();
3845                for (i=ba.size()-1; i>=0; i--) {
3846                    boolean remove = false;
3847                    final int entUid = ba.keyAt(i);
3848                    if (name != null) {
3849                        if (userId == UserHandle.USER_ALL) {
3850                            if (UserHandle.getAppId(entUid) == appId) {
3851                                remove = true;
3852                            }
3853                        } else {
3854                            if (entUid == UserHandle.getUid(userId, appId)) {
3855                                remove = true;
3856                            }
3857                        }
3858                    } else if (UserHandle.getUserId(entUid) == userId) {
3859                        remove = true;
3860                    }
3861                    if (remove) {
3862                        ba.removeAt(i);
3863                    }
3864                }
3865                if (ba.size() == 0) {
3866                    badApps.remove();
3867                }
3868            }
3869        }
3870
3871        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3872                -100, callerWillRestart, false, doit, evenPersistent,
3873                name == null ? ("force stop user " + userId) : ("force stop " + name));
3874
3875        TaskRecord lastTask = null;
3876        for (i=0; i<mMainStack.mHistory.size(); i++) {
3877            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3878            final boolean samePackage = r.packageName.equals(name)
3879                    || (name == null && r.userId == userId);
3880            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3881                    && (samePackage || r.task == lastTask)
3882                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3883                if (!doit) {
3884                    if (r.finishing) {
3885                        // If this activity is just finishing, then it is not
3886                        // interesting as far as something to stop.
3887                        continue;
3888                    }
3889                    return true;
3890                }
3891                didSomething = true;
3892                Slog.i(TAG, "  Force finishing activity " + r);
3893                if (samePackage) {
3894                    if (r.app != null) {
3895                        r.app.removed = true;
3896                    }
3897                    r.app = null;
3898                }
3899                lastTask = r.task;
3900                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3901                        null, "force-stop", true)) {
3902                    i--;
3903                }
3904            }
3905        }
3906
3907        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3908            if (!doit) {
3909                return true;
3910            }
3911            didSomething = true;
3912        }
3913
3914        if (name == null) {
3915            // Remove all sticky broadcasts from this user.
3916            mStickyBroadcasts.remove(userId);
3917        }
3918
3919        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3920        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3921                userId, providers)) {
3922            if (!doit) {
3923                return true;
3924            }
3925            didSomething = true;
3926        }
3927        N = providers.size();
3928        for (i=0; i<N; i++) {
3929            removeDyingProviderLocked(null, providers.get(i), true);
3930        }
3931
3932        if (mIntentSenderRecords.size() > 0) {
3933            Iterator<WeakReference<PendingIntentRecord>> it
3934                    = mIntentSenderRecords.values().iterator();
3935            while (it.hasNext()) {
3936                WeakReference<PendingIntentRecord> wpir = it.next();
3937                if (wpir == null) {
3938                    it.remove();
3939                    continue;
3940                }
3941                PendingIntentRecord pir = wpir.get();
3942                if (pir == null) {
3943                    it.remove();
3944                    continue;
3945                }
3946                if (name == null) {
3947                    // Stopping user, remove all objects for the user.
3948                    if (pir.key.userId != userId) {
3949                        // Not the same user, skip it.
3950                        continue;
3951                    }
3952                } else {
3953                    if (UserHandle.getAppId(pir.uid) != appId) {
3954                        // Different app id, skip it.
3955                        continue;
3956                    }
3957                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3958                        // Different user, skip it.
3959                        continue;
3960                    }
3961                    if (!pir.key.packageName.equals(name)) {
3962                        // Different package, skip it.
3963                        continue;
3964                    }
3965                }
3966                if (!doit) {
3967                    return true;
3968                }
3969                didSomething = true;
3970                it.remove();
3971                pir.canceled = true;
3972                if (pir.key.activity != null) {
3973                    pir.key.activity.pendingResults.remove(pir.ref);
3974                }
3975            }
3976        }
3977
3978        if (doit) {
3979            if (purgeCache && name != null) {
3980                AttributeCache ac = AttributeCache.instance();
3981                if (ac != null) {
3982                    ac.removePackage(name);
3983                }
3984            }
3985            if (mBooted) {
3986                mMainStack.resumeTopActivityLocked(null);
3987                mMainStack.scheduleIdleLocked();
3988            }
3989        }
3990
3991        return didSomething;
3992    }
3993
3994    private final boolean removeProcessLocked(ProcessRecord app,
3995            boolean callerWillRestart, boolean allowRestart, String reason) {
3996        final String name = app.processName;
3997        final int uid = app.uid;
3998        if (DEBUG_PROCESSES) Slog.d(
3999            TAG, "Force removing proc " + app.toShortString() + " (" + name
4000            + "/" + uid + ")");
4001
4002        mProcessNames.remove(name, uid);
4003        mIsolatedProcesses.remove(app.uid);
4004        if (mHeavyWeightProcess == app) {
4005            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4006                    mHeavyWeightProcess.userId, 0));
4007            mHeavyWeightProcess = null;
4008        }
4009        boolean needRestart = false;
4010        if (app.pid > 0 && app.pid != MY_PID) {
4011            int pid = app.pid;
4012            synchronized (mPidsSelfLocked) {
4013                mPidsSelfLocked.remove(pid);
4014                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4015            }
4016            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4017            handleAppDiedLocked(app, true, allowRestart);
4018            mLruProcesses.remove(app);
4019            Process.killProcessQuiet(pid);
4020
4021            if (app.persistent && !app.isolated) {
4022                if (!callerWillRestart) {
4023                    addAppLocked(app.info, false);
4024                } else {
4025                    needRestart = true;
4026                }
4027            }
4028        } else {
4029            mRemovedProcesses.add(app);
4030        }
4031
4032        return needRestart;
4033    }
4034
4035    private final void processStartTimedOutLocked(ProcessRecord app) {
4036        final int pid = app.pid;
4037        boolean gone = false;
4038        synchronized (mPidsSelfLocked) {
4039            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4040            if (knownApp != null && knownApp.thread == null) {
4041                mPidsSelfLocked.remove(pid);
4042                gone = true;
4043            }
4044        }
4045
4046        if (gone) {
4047            Slog.w(TAG, "Process " + app + " failed to attach");
4048            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4049                    pid, app.uid, app.processName);
4050            mProcessNames.remove(app.processName, app.uid);
4051            mIsolatedProcesses.remove(app.uid);
4052            if (mHeavyWeightProcess == app) {
4053                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4054                        mHeavyWeightProcess.userId, 0));
4055                mHeavyWeightProcess = null;
4056            }
4057            // Take care of any launching providers waiting for this process.
4058            checkAppInLaunchingProvidersLocked(app, true);
4059            // Take care of any services that are waiting for the process.
4060            mServices.processStartTimedOutLocked(app);
4061            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4062                    app.processName, app.setAdj, "start timeout");
4063            Process.killProcessQuiet(pid);
4064            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4065                Slog.w(TAG, "Unattached app died before backup, skipping");
4066                try {
4067                    IBackupManager bm = IBackupManager.Stub.asInterface(
4068                            ServiceManager.getService(Context.BACKUP_SERVICE));
4069                    bm.agentDisconnected(app.info.packageName);
4070                } catch (RemoteException e) {
4071                    // Can't happen; the backup manager is local
4072                }
4073            }
4074            if (isPendingBroadcastProcessLocked(pid)) {
4075                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4076                skipPendingBroadcastLocked(pid);
4077            }
4078        } else {
4079            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4080        }
4081    }
4082
4083    private final boolean attachApplicationLocked(IApplicationThread thread,
4084            int pid) {
4085
4086        // Find the application record that is being attached...  either via
4087        // the pid if we are running in multiple processes, or just pull the
4088        // next app record if we are emulating process with anonymous threads.
4089        ProcessRecord app;
4090        if (pid != MY_PID && pid >= 0) {
4091            synchronized (mPidsSelfLocked) {
4092                app = mPidsSelfLocked.get(pid);
4093            }
4094        } else {
4095            app = null;
4096        }
4097
4098        if (app == null) {
4099            Slog.w(TAG, "No pending application record for pid " + pid
4100                    + " (IApplicationThread " + thread + "); dropping process");
4101            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4102            if (pid > 0 && pid != MY_PID) {
4103                Process.killProcessQuiet(pid);
4104            } else {
4105                try {
4106                    thread.scheduleExit();
4107                } catch (Exception e) {
4108                    // Ignore exceptions.
4109                }
4110            }
4111            return false;
4112        }
4113
4114        // If this application record is still attached to a previous
4115        // process, clean it up now.
4116        if (app.thread != null) {
4117            handleAppDiedLocked(app, true, true);
4118        }
4119
4120        // Tell the process all about itself.
4121
4122        if (localLOGV) Slog.v(
4123                TAG, "Binding process pid " + pid + " to record " + app);
4124
4125        String processName = app.processName;
4126        try {
4127            AppDeathRecipient adr = new AppDeathRecipient(
4128                    app, pid, thread);
4129            thread.asBinder().linkToDeath(adr, 0);
4130            app.deathRecipient = adr;
4131        } catch (RemoteException e) {
4132            app.resetPackageList();
4133            startProcessLocked(app, "link fail", processName);
4134            return false;
4135        }
4136
4137        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4138
4139        app.thread = thread;
4140        app.curAdj = app.setAdj = -100;
4141        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4142        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4143        app.forcingToForeground = null;
4144        app.foregroundServices = false;
4145        app.hasShownUi = false;
4146        app.debugging = false;
4147
4148        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4149
4150        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4151        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4152
4153        if (!normalMode) {
4154            Slog.i(TAG, "Launching preboot mode app: " + app);
4155        }
4156
4157        if (localLOGV) Slog.v(
4158            TAG, "New app record " + app
4159            + " thread=" + thread.asBinder() + " pid=" + pid);
4160        try {
4161            int testMode = IApplicationThread.DEBUG_OFF;
4162            if (mDebugApp != null && mDebugApp.equals(processName)) {
4163                testMode = mWaitForDebugger
4164                    ? IApplicationThread.DEBUG_WAIT
4165                    : IApplicationThread.DEBUG_ON;
4166                app.debugging = true;
4167                if (mDebugTransient) {
4168                    mDebugApp = mOrigDebugApp;
4169                    mWaitForDebugger = mOrigWaitForDebugger;
4170                }
4171            }
4172            String profileFile = app.instrumentationProfileFile;
4173            ParcelFileDescriptor profileFd = null;
4174            boolean profileAutoStop = false;
4175            if (mProfileApp != null && mProfileApp.equals(processName)) {
4176                mProfileProc = app;
4177                profileFile = mProfileFile;
4178                profileFd = mProfileFd;
4179                profileAutoStop = mAutoStopProfiler;
4180            }
4181            boolean enableOpenGlTrace = false;
4182            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4183                enableOpenGlTrace = true;
4184                mOpenGlTraceApp = null;
4185            }
4186
4187            // If the app is being launched for restore or full backup, set it up specially
4188            boolean isRestrictedBackupMode = false;
4189            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4190                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4191                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4192                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4193            }
4194
4195            ensurePackageDexOpt(app.instrumentationInfo != null
4196                    ? app.instrumentationInfo.packageName
4197                    : app.info.packageName);
4198            if (app.instrumentationClass != null) {
4199                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4200            }
4201            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4202                    + processName + " with config " + mConfiguration);
4203            ApplicationInfo appInfo = app.instrumentationInfo != null
4204                    ? app.instrumentationInfo : app.info;
4205            app.compat = compatibilityInfoForPackageLocked(appInfo);
4206            if (profileFd != null) {
4207                profileFd = profileFd.dup();
4208            }
4209            thread.bindApplication(processName, appInfo, providers,
4210                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4211                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4212                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4213                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4214                    mCoreSettingsObserver.getCoreSettingsLocked());
4215            updateLruProcessLocked(app, false);
4216            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4217        } catch (Exception e) {
4218            // todo: Yikes!  What should we do?  For now we will try to
4219            // start another process, but that could easily get us in
4220            // an infinite loop of restarting processes...
4221            Slog.w(TAG, "Exception thrown during bind!", e);
4222
4223            app.resetPackageList();
4224            app.unlinkDeathRecipient();
4225            startProcessLocked(app, "bind fail", processName);
4226            return false;
4227        }
4228
4229        // Remove this record from the list of starting applications.
4230        mPersistentStartingProcesses.remove(app);
4231        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4232                "Attach application locked removing on hold: " + app);
4233        mProcessesOnHold.remove(app);
4234
4235        boolean badApp = false;
4236        boolean didSomething = false;
4237
4238        // See if the top visible activity is waiting to run in this process...
4239        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4240        if (hr != null && normalMode) {
4241            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4242                    && processName.equals(hr.processName)) {
4243                try {
4244                    if (mHeadless) {
4245                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4246                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4247                        didSomething = true;
4248                    }
4249                } catch (Exception e) {
4250                    Slog.w(TAG, "Exception in new application when starting activity "
4251                          + hr.intent.getComponent().flattenToShortString(), e);
4252                    badApp = true;
4253                }
4254            } else {
4255                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4256            }
4257        }
4258
4259        // Find any services that should be running in this process...
4260        if (!badApp) {
4261            try {
4262                didSomething |= mServices.attachApplicationLocked(app, processName);
4263            } catch (Exception e) {
4264                badApp = true;
4265            }
4266        }
4267
4268        // Check if a next-broadcast receiver is in this process...
4269        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4270            try {
4271                didSomething = sendPendingBroadcastsLocked(app);
4272            } catch (Exception e) {
4273                // If the app died trying to launch the receiver we declare it 'bad'
4274                badApp = true;
4275            }
4276        }
4277
4278        // Check whether the next backup agent is in this process...
4279        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4280            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4281            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4282            try {
4283                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4284                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4285                        mBackupTarget.backupMode);
4286            } catch (Exception e) {
4287                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4288                e.printStackTrace();
4289            }
4290        }
4291
4292        if (badApp) {
4293            // todo: Also need to kill application to deal with all
4294            // kinds of exceptions.
4295            handleAppDiedLocked(app, false, true);
4296            return false;
4297        }
4298
4299        if (!didSomething) {
4300            updateOomAdjLocked();
4301        }
4302
4303        return true;
4304    }
4305
4306    public final void attachApplication(IApplicationThread thread) {
4307        synchronized (this) {
4308            int callingPid = Binder.getCallingPid();
4309            final long origId = Binder.clearCallingIdentity();
4310            attachApplicationLocked(thread, callingPid);
4311            Binder.restoreCallingIdentity(origId);
4312        }
4313    }
4314
4315    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4316        final long origId = Binder.clearCallingIdentity();
4317        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4318        if (stopProfiling) {
4319            synchronized (this) {
4320                if (mProfileProc == r.app) {
4321                    if (mProfileFd != null) {
4322                        try {
4323                            mProfileFd.close();
4324                        } catch (IOException e) {
4325                        }
4326                        clearProfilerLocked();
4327                    }
4328                }
4329            }
4330        }
4331        Binder.restoreCallingIdentity(origId);
4332    }
4333
4334    void enableScreenAfterBoot() {
4335        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4336                SystemClock.uptimeMillis());
4337        mWindowManager.enableScreenAfterBoot();
4338
4339        synchronized (this) {
4340            updateEventDispatchingLocked();
4341        }
4342    }
4343
4344    public void showBootMessage(final CharSequence msg, final boolean always) {
4345        enforceNotIsolatedCaller("showBootMessage");
4346        mWindowManager.showBootMessage(msg, always);
4347    }
4348
4349    public void dismissKeyguardOnNextActivity() {
4350        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4351        final long token = Binder.clearCallingIdentity();
4352        try {
4353            synchronized (this) {
4354                if (mLockScreenShown) {
4355                    mLockScreenShown = false;
4356                    comeOutOfSleepIfNeededLocked();
4357                }
4358                mMainStack.dismissKeyguardOnNextActivityLocked();
4359            }
4360        } finally {
4361            Binder.restoreCallingIdentity(token);
4362        }
4363    }
4364
4365    final void finishBooting() {
4366        IntentFilter pkgFilter = new IntentFilter();
4367        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4368        pkgFilter.addDataScheme("package");
4369        mContext.registerReceiver(new BroadcastReceiver() {
4370            @Override
4371            public void onReceive(Context context, Intent intent) {
4372                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4373                if (pkgs != null) {
4374                    for (String pkg : pkgs) {
4375                        synchronized (ActivityManagerService.this) {
4376                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4377                                setResultCode(Activity.RESULT_OK);
4378                                return;
4379                            }
4380                        }
4381                    }
4382                }
4383            }
4384        }, pkgFilter);
4385
4386        synchronized (this) {
4387            // Ensure that any processes we had put on hold are now started
4388            // up.
4389            final int NP = mProcessesOnHold.size();
4390            if (NP > 0) {
4391                ArrayList<ProcessRecord> procs =
4392                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4393                for (int ip=0; ip<NP; ip++) {
4394                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4395                            + procs.get(ip));
4396                    startProcessLocked(procs.get(ip), "on-hold", null);
4397                }
4398            }
4399
4400            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4401                // Start looking for apps that are abusing wake locks.
4402                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4403                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4404                // Tell anyone interested that we are done booting!
4405                SystemProperties.set("sys.boot_completed", "1");
4406                SystemProperties.set("dev.bootcomplete", "1");
4407                for (int i=0; i<mStartedUsers.size(); i++) {
4408                    UserStartedState uss = mStartedUsers.valueAt(i);
4409                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4410                        uss.mState = UserStartedState.STATE_RUNNING;
4411                        final int userId = mStartedUsers.keyAt(i);
4412                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4413                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4414                        broadcastIntentLocked(null, null, intent,
4415                                null, null, 0, null, null,
4416                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4417                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4418                    }
4419                }
4420            }
4421        }
4422    }
4423
4424    final void ensureBootCompleted() {
4425        boolean booting;
4426        boolean enableScreen;
4427        synchronized (this) {
4428            booting = mBooting;
4429            mBooting = false;
4430            enableScreen = !mBooted;
4431            mBooted = true;
4432        }
4433
4434        if (booting) {
4435            finishBooting();
4436        }
4437
4438        if (enableScreen) {
4439            enableScreenAfterBoot();
4440        }
4441    }
4442
4443    public final void activityResumed(IBinder token) {
4444        final long origId = Binder.clearCallingIdentity();
4445        mMainStack.activityResumed(token);
4446        Binder.restoreCallingIdentity(origId);
4447    }
4448
4449    public final void activityPaused(IBinder token) {
4450        final long origId = Binder.clearCallingIdentity();
4451        mMainStack.activityPaused(token, false);
4452        Binder.restoreCallingIdentity(origId);
4453    }
4454
4455    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4456            CharSequence description) {
4457        if (localLOGV) Slog.v(
4458            TAG, "Activity stopped: token=" + token);
4459
4460        // Refuse possible leaked file descriptors
4461        if (icicle != null && icicle.hasFileDescriptors()) {
4462            throw new IllegalArgumentException("File descriptors passed in Bundle");
4463        }
4464
4465        ActivityRecord r = null;
4466
4467        final long origId = Binder.clearCallingIdentity();
4468
4469        synchronized (this) {
4470            r = mMainStack.isInStackLocked(token);
4471            if (r != null) {
4472                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4473            }
4474        }
4475
4476        if (r != null) {
4477            sendPendingThumbnail(r, null, null, null, false);
4478        }
4479
4480        trimApplications();
4481
4482        Binder.restoreCallingIdentity(origId);
4483    }
4484
4485    public final void activityDestroyed(IBinder token) {
4486        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4487        mMainStack.activityDestroyed(token);
4488    }
4489
4490    public String getCallingPackage(IBinder token) {
4491        synchronized (this) {
4492            ActivityRecord r = getCallingRecordLocked(token);
4493            return r != null && r.app != null ? r.info.packageName : null;
4494        }
4495    }
4496
4497    public ComponentName getCallingActivity(IBinder token) {
4498        synchronized (this) {
4499            ActivityRecord r = getCallingRecordLocked(token);
4500            return r != null ? r.intent.getComponent() : null;
4501        }
4502    }
4503
4504    private ActivityRecord getCallingRecordLocked(IBinder token) {
4505        ActivityRecord r = mMainStack.isInStackLocked(token);
4506        if (r == null) {
4507            return null;
4508        }
4509        return r.resultTo;
4510    }
4511
4512    public ComponentName getActivityClassForToken(IBinder token) {
4513        synchronized(this) {
4514            ActivityRecord r = mMainStack.isInStackLocked(token);
4515            if (r == null) {
4516                return null;
4517            }
4518            return r.intent.getComponent();
4519        }
4520    }
4521
4522    public String getPackageForToken(IBinder token) {
4523        synchronized(this) {
4524            ActivityRecord r = mMainStack.isInStackLocked(token);
4525            if (r == null) {
4526                return null;
4527            }
4528            return r.packageName;
4529        }
4530    }
4531
4532    public IIntentSender getIntentSender(int type,
4533            String packageName, IBinder token, String resultWho,
4534            int requestCode, Intent[] intents, String[] resolvedTypes,
4535            int flags, Bundle options, int userId) {
4536        enforceNotIsolatedCaller("getIntentSender");
4537        // Refuse possible leaked file descriptors
4538        if (intents != null) {
4539            if (intents.length < 1) {
4540                throw new IllegalArgumentException("Intents array length must be >= 1");
4541            }
4542            for (int i=0; i<intents.length; i++) {
4543                Intent intent = intents[i];
4544                if (intent != null) {
4545                    if (intent.hasFileDescriptors()) {
4546                        throw new IllegalArgumentException("File descriptors passed in Intent");
4547                    }
4548                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4549                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4550                        throw new IllegalArgumentException(
4551                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4552                    }
4553                    intents[i] = new Intent(intent);
4554                }
4555            }
4556            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4557                throw new IllegalArgumentException(
4558                        "Intent array length does not match resolvedTypes length");
4559            }
4560        }
4561        if (options != null) {
4562            if (options.hasFileDescriptors()) {
4563                throw new IllegalArgumentException("File descriptors passed in options");
4564            }
4565        }
4566
4567        synchronized(this) {
4568            int callingUid = Binder.getCallingUid();
4569            int origUserId = userId;
4570            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4571                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4572                    "getIntentSender", null);
4573            if (origUserId == UserHandle.USER_CURRENT) {
4574                // We don't want to evaluate this until the pending intent is
4575                // actually executed.  However, we do want to always do the
4576                // security checking for it above.
4577                userId = UserHandle.USER_CURRENT;
4578            }
4579            try {
4580                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4581                    int uid = AppGlobals.getPackageManager()
4582                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4583                    if (!UserHandle.isSameApp(callingUid, uid)) {
4584                        String msg = "Permission Denial: getIntentSender() from pid="
4585                            + Binder.getCallingPid()
4586                            + ", uid=" + Binder.getCallingUid()
4587                            + ", (need uid=" + uid + ")"
4588                            + " is not allowed to send as package " + packageName;
4589                        Slog.w(TAG, msg);
4590                        throw new SecurityException(msg);
4591                    }
4592                }
4593
4594                return getIntentSenderLocked(type, packageName, callingUid, userId,
4595                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4596
4597            } catch (RemoteException e) {
4598                throw new SecurityException(e);
4599            }
4600        }
4601    }
4602
4603    IIntentSender getIntentSenderLocked(int type, String packageName,
4604            int callingUid, int userId, IBinder token, String resultWho,
4605            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4606            Bundle options) {
4607        if (DEBUG_MU)
4608            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4609        ActivityRecord activity = null;
4610        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4611            activity = mMainStack.isInStackLocked(token);
4612            if (activity == null) {
4613                return null;
4614            }
4615            if (activity.finishing) {
4616                return null;
4617            }
4618        }
4619
4620        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4621        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4622        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4623        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4624                |PendingIntent.FLAG_UPDATE_CURRENT);
4625
4626        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4627                type, packageName, activity, resultWho,
4628                requestCode, intents, resolvedTypes, flags, options, userId);
4629        WeakReference<PendingIntentRecord> ref;
4630        ref = mIntentSenderRecords.get(key);
4631        PendingIntentRecord rec = ref != null ? ref.get() : null;
4632        if (rec != null) {
4633            if (!cancelCurrent) {
4634                if (updateCurrent) {
4635                    if (rec.key.requestIntent != null) {
4636                        rec.key.requestIntent.replaceExtras(intents != null ?
4637                                intents[intents.length - 1] : null);
4638                    }
4639                    if (intents != null) {
4640                        intents[intents.length-1] = rec.key.requestIntent;
4641                        rec.key.allIntents = intents;
4642                        rec.key.allResolvedTypes = resolvedTypes;
4643                    } else {
4644                        rec.key.allIntents = null;
4645                        rec.key.allResolvedTypes = null;
4646                    }
4647                }
4648                return rec;
4649            }
4650            rec.canceled = true;
4651            mIntentSenderRecords.remove(key);
4652        }
4653        if (noCreate) {
4654            return rec;
4655        }
4656        rec = new PendingIntentRecord(this, key, callingUid);
4657        mIntentSenderRecords.put(key, rec.ref);
4658        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4659            if (activity.pendingResults == null) {
4660                activity.pendingResults
4661                        = new HashSet<WeakReference<PendingIntentRecord>>();
4662            }
4663            activity.pendingResults.add(rec.ref);
4664        }
4665        return rec;
4666    }
4667
4668    public void cancelIntentSender(IIntentSender sender) {
4669        if (!(sender instanceof PendingIntentRecord)) {
4670            return;
4671        }
4672        synchronized(this) {
4673            PendingIntentRecord rec = (PendingIntentRecord)sender;
4674            try {
4675                int uid = AppGlobals.getPackageManager()
4676                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4677                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4678                    String msg = "Permission Denial: cancelIntentSender() from pid="
4679                        + Binder.getCallingPid()
4680                        + ", uid=" + Binder.getCallingUid()
4681                        + " is not allowed to cancel packges "
4682                        + rec.key.packageName;
4683                    Slog.w(TAG, msg);
4684                    throw new SecurityException(msg);
4685                }
4686            } catch (RemoteException e) {
4687                throw new SecurityException(e);
4688            }
4689            cancelIntentSenderLocked(rec, true);
4690        }
4691    }
4692
4693    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4694        rec.canceled = true;
4695        mIntentSenderRecords.remove(rec.key);
4696        if (cleanActivity && rec.key.activity != null) {
4697            rec.key.activity.pendingResults.remove(rec.ref);
4698        }
4699    }
4700
4701    public String getPackageForIntentSender(IIntentSender pendingResult) {
4702        if (!(pendingResult instanceof PendingIntentRecord)) {
4703            return null;
4704        }
4705        try {
4706            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4707            return res.key.packageName;
4708        } catch (ClassCastException e) {
4709        }
4710        return null;
4711    }
4712
4713    public int getUidForIntentSender(IIntentSender sender) {
4714        if (sender instanceof PendingIntentRecord) {
4715            try {
4716                PendingIntentRecord res = (PendingIntentRecord)sender;
4717                return res.uid;
4718            } catch (ClassCastException e) {
4719            }
4720        }
4721        return -1;
4722    }
4723
4724    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4725        if (!(pendingResult instanceof PendingIntentRecord)) {
4726            return false;
4727        }
4728        try {
4729            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4730            if (res.key.allIntents == null) {
4731                return false;
4732            }
4733            for (int i=0; i<res.key.allIntents.length; i++) {
4734                Intent intent = res.key.allIntents[i];
4735                if (intent.getPackage() != null && intent.getComponent() != null) {
4736                    return false;
4737                }
4738            }
4739            return true;
4740        } catch (ClassCastException e) {
4741        }
4742        return false;
4743    }
4744
4745    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4746        if (!(pendingResult instanceof PendingIntentRecord)) {
4747            return false;
4748        }
4749        try {
4750            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4751            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4752                return true;
4753            }
4754            return false;
4755        } catch (ClassCastException e) {
4756        }
4757        return false;
4758    }
4759
4760    public void setProcessLimit(int max) {
4761        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4762                "setProcessLimit()");
4763        synchronized (this) {
4764            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4765            mProcessLimitOverride = max;
4766        }
4767        trimApplications();
4768    }
4769
4770    public int getProcessLimit() {
4771        synchronized (this) {
4772            return mProcessLimitOverride;
4773        }
4774    }
4775
4776    void foregroundTokenDied(ForegroundToken token) {
4777        synchronized (ActivityManagerService.this) {
4778            synchronized (mPidsSelfLocked) {
4779                ForegroundToken cur
4780                    = mForegroundProcesses.get(token.pid);
4781                if (cur != token) {
4782                    return;
4783                }
4784                mForegroundProcesses.remove(token.pid);
4785                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4786                if (pr == null) {
4787                    return;
4788                }
4789                pr.forcingToForeground = null;
4790                pr.foregroundServices = false;
4791            }
4792            updateOomAdjLocked();
4793        }
4794    }
4795
4796    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4797        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4798                "setProcessForeground()");
4799        synchronized(this) {
4800            boolean changed = false;
4801
4802            synchronized (mPidsSelfLocked) {
4803                ProcessRecord pr = mPidsSelfLocked.get(pid);
4804                if (pr == null && isForeground) {
4805                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4806                    return;
4807                }
4808                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4809                if (oldToken != null) {
4810                    oldToken.token.unlinkToDeath(oldToken, 0);
4811                    mForegroundProcesses.remove(pid);
4812                    if (pr != null) {
4813                        pr.forcingToForeground = null;
4814                    }
4815                    changed = true;
4816                }
4817                if (isForeground && token != null) {
4818                    ForegroundToken newToken = new ForegroundToken() {
4819                        public void binderDied() {
4820                            foregroundTokenDied(this);
4821                        }
4822                    };
4823                    newToken.pid = pid;
4824                    newToken.token = token;
4825                    try {
4826                        token.linkToDeath(newToken, 0);
4827                        mForegroundProcesses.put(pid, newToken);
4828                        pr.forcingToForeground = token;
4829                        changed = true;
4830                    } catch (RemoteException e) {
4831                        // If the process died while doing this, we will later
4832                        // do the cleanup with the process death link.
4833                    }
4834                }
4835            }
4836
4837            if (changed) {
4838                updateOomAdjLocked();
4839            }
4840        }
4841    }
4842
4843    // =========================================================
4844    // PERMISSIONS
4845    // =========================================================
4846
4847    static class PermissionController extends IPermissionController.Stub {
4848        ActivityManagerService mActivityManagerService;
4849        PermissionController(ActivityManagerService activityManagerService) {
4850            mActivityManagerService = activityManagerService;
4851        }
4852
4853        public boolean checkPermission(String permission, int pid, int uid) {
4854            return mActivityManagerService.checkPermission(permission, pid,
4855                    uid) == PackageManager.PERMISSION_GRANTED;
4856        }
4857    }
4858
4859    /**
4860     * This can be called with or without the global lock held.
4861     */
4862    int checkComponentPermission(String permission, int pid, int uid,
4863            int owningUid, boolean exported) {
4864        // We might be performing an operation on behalf of an indirect binder
4865        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4866        // client identity accordingly before proceeding.
4867        Identity tlsIdentity = sCallerIdentity.get();
4868        if (tlsIdentity != null) {
4869            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4870                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4871            uid = tlsIdentity.uid;
4872            pid = tlsIdentity.pid;
4873        }
4874
4875        if (pid == MY_PID) {
4876            return PackageManager.PERMISSION_GRANTED;
4877        }
4878
4879        return ActivityManager.checkComponentPermission(permission, uid,
4880                owningUid, exported);
4881    }
4882
4883    /**
4884     * As the only public entry point for permissions checking, this method
4885     * can enforce the semantic that requesting a check on a null global
4886     * permission is automatically denied.  (Internally a null permission
4887     * string is used when calling {@link #checkComponentPermission} in cases
4888     * when only uid-based security is needed.)
4889     *
4890     * This can be called with or without the global lock held.
4891     */
4892    public int checkPermission(String permission, int pid, int uid) {
4893        if (permission == null) {
4894            return PackageManager.PERMISSION_DENIED;
4895        }
4896        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4897    }
4898
4899    /**
4900     * Binder IPC calls go through the public entry point.
4901     * This can be called with or without the global lock held.
4902     */
4903    int checkCallingPermission(String permission) {
4904        return checkPermission(permission,
4905                Binder.getCallingPid(),
4906                UserHandle.getAppId(Binder.getCallingUid()));
4907    }
4908
4909    /**
4910     * This can be called with or without the global lock held.
4911     */
4912    void enforceCallingPermission(String permission, String func) {
4913        if (checkCallingPermission(permission)
4914                == PackageManager.PERMISSION_GRANTED) {
4915            return;
4916        }
4917
4918        String msg = "Permission Denial: " + func + " from pid="
4919                + Binder.getCallingPid()
4920                + ", uid=" + Binder.getCallingUid()
4921                + " requires " + permission;
4922        Slog.w(TAG, msg);
4923        throw new SecurityException(msg);
4924    }
4925
4926    /**
4927     * Determine if UID is holding permissions required to access {@link Uri} in
4928     * the given {@link ProviderInfo}. Final permission checking is always done
4929     * in {@link ContentProvider}.
4930     */
4931    private final boolean checkHoldingPermissionsLocked(
4932            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4933        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4934                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4935
4936        if (pi.applicationInfo.uid == uid) {
4937            return true;
4938        } else if (!pi.exported) {
4939            return false;
4940        }
4941
4942        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4943        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4944        try {
4945            // check if target holds top-level <provider> permissions
4946            if (!readMet && pi.readPermission != null
4947                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4948                readMet = true;
4949            }
4950            if (!writeMet && pi.writePermission != null
4951                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4952                writeMet = true;
4953            }
4954
4955            // track if unprotected read/write is allowed; any denied
4956            // <path-permission> below removes this ability
4957            boolean allowDefaultRead = pi.readPermission == null;
4958            boolean allowDefaultWrite = pi.writePermission == null;
4959
4960            // check if target holds any <path-permission> that match uri
4961            final PathPermission[] pps = pi.pathPermissions;
4962            if (pps != null) {
4963                final String path = uri.getPath();
4964                int i = pps.length;
4965                while (i > 0 && (!readMet || !writeMet)) {
4966                    i--;
4967                    PathPermission pp = pps[i];
4968                    if (pp.match(path)) {
4969                        if (!readMet) {
4970                            final String pprperm = pp.getReadPermission();
4971                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4972                                    + pprperm + " for " + pp.getPath()
4973                                    + ": match=" + pp.match(path)
4974                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4975                            if (pprperm != null) {
4976                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4977                                    readMet = true;
4978                                } else {
4979                                    allowDefaultRead = false;
4980                                }
4981                            }
4982                        }
4983                        if (!writeMet) {
4984                            final String ppwperm = pp.getWritePermission();
4985                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4986                                    + ppwperm + " for " + pp.getPath()
4987                                    + ": match=" + pp.match(path)
4988                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4989                            if (ppwperm != null) {
4990                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4991                                    writeMet = true;
4992                                } else {
4993                                    allowDefaultWrite = false;
4994                                }
4995                            }
4996                        }
4997                    }
4998                }
4999            }
5000
5001            // grant unprotected <provider> read/write, if not blocked by
5002            // <path-permission> above
5003            if (allowDefaultRead) readMet = true;
5004            if (allowDefaultWrite) writeMet = true;
5005
5006        } catch (RemoteException e) {
5007            return false;
5008        }
5009
5010        return readMet && writeMet;
5011    }
5012
5013    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5014            int modeFlags) {
5015        // Root gets to do everything.
5016        if (uid == 0) {
5017            return true;
5018        }
5019        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5020        if (perms == null) return false;
5021        UriPermission perm = perms.get(uri);
5022        if (perm == null) return false;
5023        return (modeFlags&perm.modeFlags) == modeFlags;
5024    }
5025
5026    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5027        enforceNotIsolatedCaller("checkUriPermission");
5028
5029        // Another redirected-binder-call permissions check as in
5030        // {@link checkComponentPermission}.
5031        Identity tlsIdentity = sCallerIdentity.get();
5032        if (tlsIdentity != null) {
5033            uid = tlsIdentity.uid;
5034            pid = tlsIdentity.pid;
5035        }
5036
5037        // Our own process gets to do everything.
5038        if (pid == MY_PID) {
5039            return PackageManager.PERMISSION_GRANTED;
5040        }
5041        synchronized(this) {
5042            return checkUriPermissionLocked(uri, uid, modeFlags)
5043                    ? PackageManager.PERMISSION_GRANTED
5044                    : PackageManager.PERMISSION_DENIED;
5045        }
5046    }
5047
5048    /**
5049     * Check if the targetPkg can be granted permission to access uri by
5050     * the callingUid using the given modeFlags.  Throws a security exception
5051     * if callingUid is not allowed to do this.  Returns the uid of the target
5052     * if the URI permission grant should be performed; returns -1 if it is not
5053     * needed (for example targetPkg already has permission to access the URI).
5054     * If you already know the uid of the target, you can supply it in
5055     * lastTargetUid else set that to -1.
5056     */
5057    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5058            Uri uri, int modeFlags, int lastTargetUid) {
5059        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5060                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5061        if (modeFlags == 0) {
5062            return -1;
5063        }
5064
5065        if (targetPkg != null) {
5066            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5067                    "Checking grant " + targetPkg + " permission to " + uri);
5068        }
5069
5070        final IPackageManager pm = AppGlobals.getPackageManager();
5071
5072        // If this is not a content: uri, we can't do anything with it.
5073        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5074            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5075                    "Can't grant URI permission for non-content URI: " + uri);
5076            return -1;
5077        }
5078
5079        String name = uri.getAuthority();
5080        ProviderInfo pi = null;
5081        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5082                UserHandle.getUserId(callingUid));
5083        if (cpr != null) {
5084            pi = cpr.info;
5085        } else {
5086            try {
5087                pi = pm.resolveContentProvider(name,
5088                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5089                        UserHandle.getUserId(callingUid));
5090            } catch (RemoteException ex) {
5091            }
5092        }
5093        if (pi == null) {
5094            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5095            return -1;
5096        }
5097
5098        int targetUid = lastTargetUid;
5099        if (targetUid < 0 && targetPkg != null) {
5100            try {
5101                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5102                if (targetUid < 0) {
5103                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5104                            "Can't grant URI permission no uid for: " + targetPkg);
5105                    return -1;
5106                }
5107            } catch (RemoteException ex) {
5108                return -1;
5109            }
5110        }
5111
5112        if (targetUid >= 0) {
5113            // First...  does the target actually need this permission?
5114            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5115                // No need to grant the target this permission.
5116                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5117                        "Target " + targetPkg + " already has full permission to " + uri);
5118                return -1;
5119            }
5120        } else {
5121            // First...  there is no target package, so can anyone access it?
5122            boolean allowed = pi.exported;
5123            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5124                if (pi.readPermission != null) {
5125                    allowed = false;
5126                }
5127            }
5128            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5129                if (pi.writePermission != null) {
5130                    allowed = false;
5131                }
5132            }
5133            if (allowed) {
5134                return -1;
5135            }
5136        }
5137
5138        // Second...  is the provider allowing granting of URI permissions?
5139        if (!pi.grantUriPermissions) {
5140            throw new SecurityException("Provider " + pi.packageName
5141                    + "/" + pi.name
5142                    + " does not allow granting of Uri permissions (uri "
5143                    + uri + ")");
5144        }
5145        if (pi.uriPermissionPatterns != null) {
5146            final int N = pi.uriPermissionPatterns.length;
5147            boolean allowed = false;
5148            for (int i=0; i<N; i++) {
5149                if (pi.uriPermissionPatterns[i] != null
5150                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5151                    allowed = true;
5152                    break;
5153                }
5154            }
5155            if (!allowed) {
5156                throw new SecurityException("Provider " + pi.packageName
5157                        + "/" + pi.name
5158                        + " does not allow granting of permission to path of Uri "
5159                        + uri);
5160            }
5161        }
5162
5163        // Third...  does the caller itself have permission to access
5164        // this uri?
5165        if (callingUid != Process.myUid()) {
5166            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5167                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5168                    throw new SecurityException("Uid " + callingUid
5169                            + " does not have permission to uri " + uri);
5170                }
5171            }
5172        }
5173
5174        return targetUid;
5175    }
5176
5177    public int checkGrantUriPermission(int callingUid, String targetPkg,
5178            Uri uri, int modeFlags) {
5179        enforceNotIsolatedCaller("checkGrantUriPermission");
5180        synchronized(this) {
5181            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5182        }
5183    }
5184
5185    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5186            Uri uri, int modeFlags, UriPermissionOwner owner) {
5187        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5188                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5189        if (modeFlags == 0) {
5190            return;
5191        }
5192
5193        // So here we are: the caller has the assumed permission
5194        // to the uri, and the target doesn't.  Let's now give this to
5195        // the target.
5196
5197        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5198                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5199
5200        HashMap<Uri, UriPermission> targetUris
5201                = mGrantedUriPermissions.get(targetUid);
5202        if (targetUris == null) {
5203            targetUris = new HashMap<Uri, UriPermission>();
5204            mGrantedUriPermissions.put(targetUid, targetUris);
5205        }
5206
5207        UriPermission perm = targetUris.get(uri);
5208        if (perm == null) {
5209            perm = new UriPermission(targetUid, uri);
5210            targetUris.put(uri, perm);
5211        }
5212
5213        perm.modeFlags |= modeFlags;
5214        if (owner == null) {
5215            perm.globalModeFlags |= modeFlags;
5216        } else {
5217            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5218                 perm.readOwners.add(owner);
5219                 owner.addReadPermission(perm);
5220            }
5221            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5222                 perm.writeOwners.add(owner);
5223                 owner.addWritePermission(perm);
5224            }
5225        }
5226    }
5227
5228    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5229            int modeFlags, UriPermissionOwner owner) {
5230        if (targetPkg == null) {
5231            throw new NullPointerException("targetPkg");
5232        }
5233
5234        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5235        if (targetUid < 0) {
5236            return;
5237        }
5238
5239        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5240    }
5241
5242    static class NeededUriGrants extends ArrayList<Uri> {
5243        final String targetPkg;
5244        final int targetUid;
5245        final int flags;
5246
5247        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5248            targetPkg = _targetPkg;
5249            targetUid = _targetUid;
5250            flags = _flags;
5251        }
5252    }
5253
5254    /**
5255     * Like checkGrantUriPermissionLocked, but takes an Intent.
5256     */
5257    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5258            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5259        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5260                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5261                + " clip=" + (intent != null ? intent.getClipData() : null)
5262                + " from " + intent + "; flags=0x"
5263                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5264
5265        if (targetPkg == null) {
5266            throw new NullPointerException("targetPkg");
5267        }
5268
5269        if (intent == null) {
5270            return null;
5271        }
5272        Uri data = intent.getData();
5273        ClipData clip = intent.getClipData();
5274        if (data == null && clip == null) {
5275            return null;
5276        }
5277        if (data != null) {
5278            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5279                mode, needed != null ? needed.targetUid : -1);
5280            if (target > 0) {
5281                if (needed == null) {
5282                    needed = new NeededUriGrants(targetPkg, target, mode);
5283                }
5284                needed.add(data);
5285            }
5286        }
5287        if (clip != null) {
5288            for (int i=0; i<clip.getItemCount(); i++) {
5289                Uri uri = clip.getItemAt(i).getUri();
5290                if (uri != null) {
5291                    int target = -1;
5292                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5293                            mode, needed != null ? needed.targetUid : -1);
5294                    if (target > 0) {
5295                        if (needed == null) {
5296                            needed = new NeededUriGrants(targetPkg, target, mode);
5297                        }
5298                        needed.add(uri);
5299                    }
5300                } else {
5301                    Intent clipIntent = clip.getItemAt(i).getIntent();
5302                    if (clipIntent != null) {
5303                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5304                                callingUid, targetPkg, clipIntent, mode, needed);
5305                        if (newNeeded != null) {
5306                            needed = newNeeded;
5307                        }
5308                    }
5309                }
5310            }
5311        }
5312
5313        return needed;
5314    }
5315
5316    /**
5317     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5318     */
5319    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5320            UriPermissionOwner owner) {
5321        if (needed != null) {
5322            for (int i=0; i<needed.size(); i++) {
5323                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5324                        needed.get(i), needed.flags, owner);
5325            }
5326        }
5327    }
5328
5329    void grantUriPermissionFromIntentLocked(int callingUid,
5330            String targetPkg, Intent intent, UriPermissionOwner owner) {
5331        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5332                intent, intent != null ? intent.getFlags() : 0, null);
5333        if (needed == null) {
5334            return;
5335        }
5336
5337        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5338    }
5339
5340    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5341            Uri uri, int modeFlags) {
5342        enforceNotIsolatedCaller("grantUriPermission");
5343        synchronized(this) {
5344            final ProcessRecord r = getRecordForAppLocked(caller);
5345            if (r == null) {
5346                throw new SecurityException("Unable to find app for caller "
5347                        + caller
5348                        + " when granting permission to uri " + uri);
5349            }
5350            if (targetPkg == null) {
5351                throw new IllegalArgumentException("null target");
5352            }
5353            if (uri == null) {
5354                throw new IllegalArgumentException("null uri");
5355            }
5356
5357            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5358                    null);
5359        }
5360    }
5361
5362    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5363        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5364                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5365            HashMap<Uri, UriPermission> perms
5366                    = mGrantedUriPermissions.get(perm.uid);
5367            if (perms != null) {
5368                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5369                        "Removing " + perm.uid + " permission to " + perm.uri);
5370                perms.remove(perm.uri);
5371                if (perms.size() == 0) {
5372                    mGrantedUriPermissions.remove(perm.uid);
5373                }
5374            }
5375        }
5376    }
5377
5378    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5379            int modeFlags) {
5380        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5381                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5382        if (modeFlags == 0) {
5383            return;
5384        }
5385
5386        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5387                "Revoking all granted permissions to " + uri);
5388
5389        final IPackageManager pm = AppGlobals.getPackageManager();
5390
5391        final String authority = uri.getAuthority();
5392        ProviderInfo pi = null;
5393        int userId = UserHandle.getUserId(callingUid);
5394        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5395        if (cpr != null) {
5396            pi = cpr.info;
5397        } else {
5398            try {
5399                pi = pm.resolveContentProvider(authority,
5400                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5401            } catch (RemoteException ex) {
5402            }
5403        }
5404        if (pi == null) {
5405            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5406            return;
5407        }
5408
5409        // Does the caller have this permission on the URI?
5410        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5411            // Right now, if you are not the original owner of the permission,
5412            // you are not allowed to revoke it.
5413            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5414                throw new SecurityException("Uid " + callingUid
5415                        + " does not have permission to uri " + uri);
5416            //}
5417        }
5418
5419        // Go through all of the permissions and remove any that match.
5420        final List<String> SEGMENTS = uri.getPathSegments();
5421        if (SEGMENTS != null) {
5422            final int NS = SEGMENTS.size();
5423            int N = mGrantedUriPermissions.size();
5424            for (int i=0; i<N; i++) {
5425                HashMap<Uri, UriPermission> perms
5426                        = mGrantedUriPermissions.valueAt(i);
5427                Iterator<UriPermission> it = perms.values().iterator();
5428            toploop:
5429                while (it.hasNext()) {
5430                    UriPermission perm = it.next();
5431                    Uri targetUri = perm.uri;
5432                    if (!authority.equals(targetUri.getAuthority())) {
5433                        continue;
5434                    }
5435                    List<String> targetSegments = targetUri.getPathSegments();
5436                    if (targetSegments == null) {
5437                        continue;
5438                    }
5439                    if (targetSegments.size() < NS) {
5440                        continue;
5441                    }
5442                    for (int j=0; j<NS; j++) {
5443                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5444                            continue toploop;
5445                        }
5446                    }
5447                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5448                            "Revoking " + perm.uid + " permission to " + perm.uri);
5449                    perm.clearModes(modeFlags);
5450                    if (perm.modeFlags == 0) {
5451                        it.remove();
5452                    }
5453                }
5454                if (perms.size() == 0) {
5455                    mGrantedUriPermissions.remove(
5456                            mGrantedUriPermissions.keyAt(i));
5457                    N--;
5458                    i--;
5459                }
5460            }
5461        }
5462    }
5463
5464    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5465            int modeFlags) {
5466        enforceNotIsolatedCaller("revokeUriPermission");
5467        synchronized(this) {
5468            final ProcessRecord r = getRecordForAppLocked(caller);
5469            if (r == null) {
5470                throw new SecurityException("Unable to find app for caller "
5471                        + caller
5472                        + " when revoking permission to uri " + uri);
5473            }
5474            if (uri == null) {
5475                Slog.w(TAG, "revokeUriPermission: null uri");
5476                return;
5477            }
5478
5479            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5480                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5481            if (modeFlags == 0) {
5482                return;
5483            }
5484
5485            final IPackageManager pm = AppGlobals.getPackageManager();
5486
5487            final String authority = uri.getAuthority();
5488            ProviderInfo pi = null;
5489            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5490            if (cpr != null) {
5491                pi = cpr.info;
5492            } else {
5493                try {
5494                    pi = pm.resolveContentProvider(authority,
5495                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5496                } catch (RemoteException ex) {
5497                }
5498            }
5499            if (pi == null) {
5500                Slog.w(TAG, "No content provider found for permission revoke: "
5501                        + uri.toSafeString());
5502                return;
5503            }
5504
5505            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5506        }
5507    }
5508
5509    @Override
5510    public IBinder newUriPermissionOwner(String name) {
5511        enforceNotIsolatedCaller("newUriPermissionOwner");
5512        synchronized(this) {
5513            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5514            return owner.getExternalTokenLocked();
5515        }
5516    }
5517
5518    @Override
5519    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5520            Uri uri, int modeFlags) {
5521        synchronized(this) {
5522            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5523            if (owner == null) {
5524                throw new IllegalArgumentException("Unknown owner: " + token);
5525            }
5526            if (fromUid != Binder.getCallingUid()) {
5527                if (Binder.getCallingUid() != Process.myUid()) {
5528                    // Only system code can grant URI permissions on behalf
5529                    // of other users.
5530                    throw new SecurityException("nice try");
5531                }
5532            }
5533            if (targetPkg == null) {
5534                throw new IllegalArgumentException("null target");
5535            }
5536            if (uri == null) {
5537                throw new IllegalArgumentException("null uri");
5538            }
5539
5540            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5541        }
5542    }
5543
5544    @Override
5545    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5546        synchronized(this) {
5547            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5548            if (owner == null) {
5549                throw new IllegalArgumentException("Unknown owner: " + token);
5550            }
5551
5552            if (uri == null) {
5553                owner.removeUriPermissionsLocked(mode);
5554            } else {
5555                owner.removeUriPermissionLocked(uri, mode);
5556            }
5557        }
5558    }
5559
5560    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5561        synchronized (this) {
5562            ProcessRecord app =
5563                who != null ? getRecordForAppLocked(who) : null;
5564            if (app == null) return;
5565
5566            Message msg = Message.obtain();
5567            msg.what = WAIT_FOR_DEBUGGER_MSG;
5568            msg.obj = app;
5569            msg.arg1 = waiting ? 1 : 0;
5570            mHandler.sendMessage(msg);
5571        }
5572    }
5573
5574    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5575        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5576        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5577        outInfo.availMem = Process.getFreeMemory();
5578        outInfo.totalMem = Process.getTotalMemory();
5579        outInfo.threshold = homeAppMem;
5580        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5581        outInfo.hiddenAppThreshold = hiddenAppMem;
5582        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5583                ProcessList.SERVICE_ADJ);
5584        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5585                ProcessList.VISIBLE_APP_ADJ);
5586        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5587                ProcessList.FOREGROUND_APP_ADJ);
5588    }
5589
5590    // =========================================================
5591    // TASK MANAGEMENT
5592    // =========================================================
5593
5594    public List getTasks(int maxNum, int flags,
5595                         IThumbnailReceiver receiver) {
5596        ArrayList list = new ArrayList();
5597
5598        PendingThumbnailsRecord pending = null;
5599        IApplicationThread topThumbnail = null;
5600        ActivityRecord topRecord = null;
5601
5602        synchronized(this) {
5603            if (localLOGV) Slog.v(
5604                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5605                + ", receiver=" + receiver);
5606
5607            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5608                    != PackageManager.PERMISSION_GRANTED) {
5609                if (receiver != null) {
5610                    // If the caller wants to wait for pending thumbnails,
5611                    // it ain't gonna get them.
5612                    try {
5613                        receiver.finished();
5614                    } catch (RemoteException ex) {
5615                    }
5616                }
5617                String msg = "Permission Denial: getTasks() from pid="
5618                        + Binder.getCallingPid()
5619                        + ", uid=" + Binder.getCallingUid()
5620                        + " requires " + android.Manifest.permission.GET_TASKS;
5621                Slog.w(TAG, msg);
5622                throw new SecurityException(msg);
5623            }
5624
5625            int pos = mMainStack.mHistory.size()-1;
5626            ActivityRecord next =
5627                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5628            ActivityRecord top = null;
5629            TaskRecord curTask = null;
5630            int numActivities = 0;
5631            int numRunning = 0;
5632            while (pos >= 0 && maxNum > 0) {
5633                final ActivityRecord r = next;
5634                pos--;
5635                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5636
5637                // Initialize state for next task if needed.
5638                if (top == null ||
5639                        (top.state == ActivityState.INITIALIZING
5640                            && top.task == r.task)) {
5641                    top = r;
5642                    curTask = r.task;
5643                    numActivities = numRunning = 0;
5644                }
5645
5646                // Add 'r' into the current task.
5647                numActivities++;
5648                if (r.app != null && r.app.thread != null) {
5649                    numRunning++;
5650                }
5651
5652                if (localLOGV) Slog.v(
5653                    TAG, r.intent.getComponent().flattenToShortString()
5654                    + ": task=" + r.task);
5655
5656                // If the next one is a different task, generate a new
5657                // TaskInfo entry for what we have.
5658                if (next == null || next.task != curTask) {
5659                    ActivityManager.RunningTaskInfo ci
5660                            = new ActivityManager.RunningTaskInfo();
5661                    ci.id = curTask.taskId;
5662                    ci.baseActivity = r.intent.getComponent();
5663                    ci.topActivity = top.intent.getComponent();
5664                    if (top.thumbHolder != null) {
5665                        ci.description = top.thumbHolder.lastDescription;
5666                    }
5667                    ci.numActivities = numActivities;
5668                    ci.numRunning = numRunning;
5669                    //System.out.println(
5670                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5671                    if (ci.thumbnail == null && receiver != null) {
5672                        if (localLOGV) Slog.v(
5673                            TAG, "State=" + top.state + "Idle=" + top.idle
5674                            + " app=" + top.app
5675                            + " thr=" + (top.app != null ? top.app.thread : null));
5676                        if (top.state == ActivityState.RESUMED
5677                                || top.state == ActivityState.PAUSING) {
5678                            if (top.idle && top.app != null
5679                                && top.app.thread != null) {
5680                                topRecord = top;
5681                                topThumbnail = top.app.thread;
5682                            } else {
5683                                top.thumbnailNeeded = true;
5684                            }
5685                        }
5686                        if (pending == null) {
5687                            pending = new PendingThumbnailsRecord(receiver);
5688                        }
5689                        pending.pendingRecords.add(top);
5690                    }
5691                    list.add(ci);
5692                    maxNum--;
5693                    top = null;
5694                }
5695            }
5696
5697            if (pending != null) {
5698                mPendingThumbnails.add(pending);
5699            }
5700        }
5701
5702        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5703
5704        if (topThumbnail != null) {
5705            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5706            try {
5707                topThumbnail.requestThumbnail(topRecord.appToken);
5708            } catch (Exception e) {
5709                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5710                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5711            }
5712        }
5713
5714        if (pending == null && receiver != null) {
5715            // In this case all thumbnails were available and the client
5716            // is being asked to be told when the remaining ones come in...
5717            // which is unusually, since the top-most currently running
5718            // activity should never have a canned thumbnail!  Oh well.
5719            try {
5720                receiver.finished();
5721            } catch (RemoteException ex) {
5722            }
5723        }
5724
5725        return list;
5726    }
5727
5728    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5729            int flags, int userId) {
5730        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5731                false, true, "getRecentTasks", null);
5732
5733        synchronized (this) {
5734            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5735                    "getRecentTasks()");
5736            final boolean detailed = checkCallingPermission(
5737                    android.Manifest.permission.GET_DETAILED_TASKS)
5738                    == PackageManager.PERMISSION_GRANTED;
5739
5740            IPackageManager pm = AppGlobals.getPackageManager();
5741
5742            final int N = mRecentTasks.size();
5743            ArrayList<ActivityManager.RecentTaskInfo> res
5744                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5745                            maxNum < N ? maxNum : N);
5746            for (int i=0; i<N && maxNum > 0; i++) {
5747                TaskRecord tr = mRecentTasks.get(i);
5748                // Only add calling user's recent tasks
5749                if (tr.userId != userId) continue;
5750                // Return the entry if desired by the caller.  We always return
5751                // the first entry, because callers always expect this to be the
5752                // foreground app.  We may filter others if the caller has
5753                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5754                // we should exclude the entry.
5755
5756                if (i == 0
5757                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5758                        || (tr.intent == null)
5759                        || ((tr.intent.getFlags()
5760                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5761                    ActivityManager.RecentTaskInfo rti
5762                            = new ActivityManager.RecentTaskInfo();
5763                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5764                    rti.persistentId = tr.taskId;
5765                    rti.baseIntent = new Intent(
5766                            tr.intent != null ? tr.intent : tr.affinityIntent);
5767                    if (!detailed) {
5768                        rti.baseIntent.replaceExtras((Bundle)null);
5769                    }
5770                    rti.origActivity = tr.origActivity;
5771                    rti.description = tr.lastDescription;
5772
5773                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5774                        // Check whether this activity is currently available.
5775                        try {
5776                            if (rti.origActivity != null) {
5777                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5778                                        == null) {
5779                                    continue;
5780                                }
5781                            } else if (rti.baseIntent != null) {
5782                                if (pm.queryIntentActivities(rti.baseIntent,
5783                                        null, 0, userId) == null) {
5784                                    continue;
5785                                }
5786                            }
5787                        } catch (RemoteException e) {
5788                            // Will never happen.
5789                        }
5790                    }
5791
5792                    res.add(rti);
5793                    maxNum--;
5794                }
5795            }
5796            return res;
5797        }
5798    }
5799
5800    private TaskRecord taskForIdLocked(int id) {
5801        final int N = mRecentTasks.size();
5802        for (int i=0; i<N; i++) {
5803            TaskRecord tr = mRecentTasks.get(i);
5804            if (tr.taskId == id) {
5805                return tr;
5806            }
5807        }
5808        return null;
5809    }
5810
5811    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5812        synchronized (this) {
5813            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5814                    "getTaskThumbnails()");
5815            TaskRecord tr = taskForIdLocked(id);
5816            if (tr != null) {
5817                return mMainStack.getTaskThumbnailsLocked(tr);
5818            }
5819        }
5820        return null;
5821    }
5822
5823    public Bitmap getTaskTopThumbnail(int id) {
5824        synchronized (this) {
5825            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5826                    "getTaskTopThumbnail()");
5827            TaskRecord tr = taskForIdLocked(id);
5828            if (tr != null) {
5829                return mMainStack.getTaskTopThumbnailLocked(tr);
5830            }
5831        }
5832        return null;
5833    }
5834
5835    public boolean removeSubTask(int taskId, int subTaskIndex) {
5836        synchronized (this) {
5837            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5838                    "removeSubTask()");
5839            long ident = Binder.clearCallingIdentity();
5840            try {
5841                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5842                        true) != null;
5843            } finally {
5844                Binder.restoreCallingIdentity(ident);
5845            }
5846        }
5847    }
5848
5849    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5850        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5851        Intent baseIntent = new Intent(
5852                tr.intent != null ? tr.intent : tr.affinityIntent);
5853        ComponentName component = baseIntent.getComponent();
5854        if (component == null) {
5855            Slog.w(TAG, "Now component for base intent of task: " + tr);
5856            return;
5857        }
5858
5859        // Find any running services associated with this app.
5860        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5861
5862        if (killProcesses) {
5863            // Find any running processes associated with this app.
5864            final String pkg = component.getPackageName();
5865            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5866            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5867            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5868                for (int i=0; i<uids.size(); i++) {
5869                    ProcessRecord proc = uids.valueAt(i);
5870                    if (proc.userId != tr.userId) {
5871                        continue;
5872                    }
5873                    if (!proc.pkgList.contains(pkg)) {
5874                        continue;
5875                    }
5876                    procs.add(proc);
5877                }
5878            }
5879
5880            // Kill the running processes.
5881            for (int i=0; i<procs.size(); i++) {
5882                ProcessRecord pr = procs.get(i);
5883                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5884                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5885                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5886                            pr.processName, pr.setAdj, "remove task");
5887                    pr.killedBackground = true;
5888                    Process.killProcessQuiet(pr.pid);
5889                } else {
5890                    pr.waitingToKill = "remove task";
5891                }
5892            }
5893        }
5894    }
5895
5896    public boolean removeTask(int taskId, int flags) {
5897        synchronized (this) {
5898            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5899                    "removeTask()");
5900            long ident = Binder.clearCallingIdentity();
5901            try {
5902                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5903                        false);
5904                if (r != null) {
5905                    mRecentTasks.remove(r.task);
5906                    cleanUpRemovedTaskLocked(r.task, flags);
5907                    return true;
5908                } else {
5909                    TaskRecord tr = null;
5910                    int i=0;
5911                    while (i < mRecentTasks.size()) {
5912                        TaskRecord t = mRecentTasks.get(i);
5913                        if (t.taskId == taskId) {
5914                            tr = t;
5915                            break;
5916                        }
5917                        i++;
5918                    }
5919                    if (tr != null) {
5920                        if (tr.numActivities <= 0) {
5921                            // Caller is just removing a recent task that is
5922                            // not actively running.  That is easy!
5923                            mRecentTasks.remove(i);
5924                            cleanUpRemovedTaskLocked(tr, flags);
5925                            return true;
5926                        } else {
5927                            Slog.w(TAG, "removeTask: task " + taskId
5928                                    + " does not have activities to remove, "
5929                                    + " but numActivities=" + tr.numActivities
5930                                    + ": " + tr);
5931                        }
5932                    }
5933                }
5934            } finally {
5935                Binder.restoreCallingIdentity(ident);
5936            }
5937        }
5938        return false;
5939    }
5940
5941    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5942        int j;
5943        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5944        TaskRecord jt = startTask;
5945
5946        // First look backwards
5947        for (j=startIndex-1; j>=0; j--) {
5948            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5949            if (r.task != jt) {
5950                jt = r.task;
5951                if (affinity.equals(jt.affinity)) {
5952                    return j;
5953                }
5954            }
5955        }
5956
5957        // Now look forwards
5958        final int N = mMainStack.mHistory.size();
5959        jt = startTask;
5960        for (j=startIndex+1; j<N; j++) {
5961            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5962            if (r.task != jt) {
5963                if (affinity.equals(jt.affinity)) {
5964                    return j;
5965                }
5966                jt = r.task;
5967            }
5968        }
5969
5970        // Might it be at the top?
5971        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5972            return N-1;
5973        }
5974
5975        return -1;
5976    }
5977
5978    /**
5979     * TODO: Add mController hook
5980     */
5981    public void moveTaskToFront(int task, int flags, Bundle options) {
5982        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5983                "moveTaskToFront()");
5984
5985        synchronized(this) {
5986            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5987                    Binder.getCallingUid(), "Task to front")) {
5988                ActivityOptions.abort(options);
5989                return;
5990            }
5991            final long origId = Binder.clearCallingIdentity();
5992            try {
5993                TaskRecord tr = taskForIdLocked(task);
5994                if (tr != null) {
5995                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5996                        mMainStack.mUserLeaving = true;
5997                    }
5998                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5999                        // Caller wants the home activity moved with it.  To accomplish this,
6000                        // we'll just move the home task to the top first.
6001                        mMainStack.moveHomeToFrontLocked();
6002                    }
6003                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6004                    return;
6005                }
6006                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6007                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6008                    if (hr.task.taskId == task) {
6009                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6010                            mMainStack.mUserLeaving = true;
6011                        }
6012                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6013                            // Caller wants the home activity moved with it.  To accomplish this,
6014                            // we'll just move the home task to the top first.
6015                            mMainStack.moveHomeToFrontLocked();
6016                        }
6017                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6018                        return;
6019                    }
6020                }
6021            } finally {
6022                Binder.restoreCallingIdentity(origId);
6023            }
6024            ActivityOptions.abort(options);
6025        }
6026    }
6027
6028    public void moveTaskToBack(int task) {
6029        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6030                "moveTaskToBack()");
6031
6032        synchronized(this) {
6033            if (mMainStack.mResumedActivity != null
6034                    && mMainStack.mResumedActivity.task.taskId == task) {
6035                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6036                        Binder.getCallingUid(), "Task to back")) {
6037                    return;
6038                }
6039            }
6040            final long origId = Binder.clearCallingIdentity();
6041            mMainStack.moveTaskToBackLocked(task, null);
6042            Binder.restoreCallingIdentity(origId);
6043        }
6044    }
6045
6046    /**
6047     * Moves an activity, and all of the other activities within the same task, to the bottom
6048     * of the history stack.  The activity's order within the task is unchanged.
6049     *
6050     * @param token A reference to the activity we wish to move
6051     * @param nonRoot If false then this only works if the activity is the root
6052     *                of a task; if true it will work for any activity in a task.
6053     * @return Returns true if the move completed, false if not.
6054     */
6055    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6056        enforceNotIsolatedCaller("moveActivityTaskToBack");
6057        synchronized(this) {
6058            final long origId = Binder.clearCallingIdentity();
6059            int taskId = getTaskForActivityLocked(token, !nonRoot);
6060            if (taskId >= 0) {
6061                return mMainStack.moveTaskToBackLocked(taskId, null);
6062            }
6063            Binder.restoreCallingIdentity(origId);
6064        }
6065        return false;
6066    }
6067
6068    public void moveTaskBackwards(int task) {
6069        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6070                "moveTaskBackwards()");
6071
6072        synchronized(this) {
6073            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6074                    Binder.getCallingUid(), "Task backwards")) {
6075                return;
6076            }
6077            final long origId = Binder.clearCallingIdentity();
6078            moveTaskBackwardsLocked(task);
6079            Binder.restoreCallingIdentity(origId);
6080        }
6081    }
6082
6083    private final void moveTaskBackwardsLocked(int task) {
6084        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6085    }
6086
6087    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6088        synchronized(this) {
6089            return getTaskForActivityLocked(token, onlyRoot);
6090        }
6091    }
6092
6093    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6094        final int N = mMainStack.mHistory.size();
6095        TaskRecord lastTask = null;
6096        for (int i=0; i<N; i++) {
6097            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6098            if (r.appToken == token) {
6099                if (!onlyRoot || lastTask != r.task) {
6100                    return r.task.taskId;
6101                }
6102                return -1;
6103            }
6104            lastTask = r.task;
6105        }
6106
6107        return -1;
6108    }
6109
6110    // =========================================================
6111    // THUMBNAILS
6112    // =========================================================
6113
6114    public void reportThumbnail(IBinder token,
6115            Bitmap thumbnail, CharSequence description) {
6116        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6117        final long origId = Binder.clearCallingIdentity();
6118        sendPendingThumbnail(null, token, thumbnail, description, true);
6119        Binder.restoreCallingIdentity(origId);
6120    }
6121
6122    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6123            Bitmap thumbnail, CharSequence description, boolean always) {
6124        TaskRecord task = null;
6125        ArrayList receivers = null;
6126
6127        //System.out.println("Send pending thumbnail: " + r);
6128
6129        synchronized(this) {
6130            if (r == null) {
6131                r = mMainStack.isInStackLocked(token);
6132                if (r == null) {
6133                    return;
6134                }
6135            }
6136            if (thumbnail == null && r.thumbHolder != null) {
6137                thumbnail = r.thumbHolder.lastThumbnail;
6138                description = r.thumbHolder.lastDescription;
6139            }
6140            if (thumbnail == null && !always) {
6141                // If there is no thumbnail, and this entry is not actually
6142                // going away, then abort for now and pick up the next
6143                // thumbnail we get.
6144                return;
6145            }
6146            task = r.task;
6147
6148            int N = mPendingThumbnails.size();
6149            int i=0;
6150            while (i<N) {
6151                PendingThumbnailsRecord pr =
6152                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6153                //System.out.println("Looking in " + pr.pendingRecords);
6154                if (pr.pendingRecords.remove(r)) {
6155                    if (receivers == null) {
6156                        receivers = new ArrayList();
6157                    }
6158                    receivers.add(pr);
6159                    if (pr.pendingRecords.size() == 0) {
6160                        pr.finished = true;
6161                        mPendingThumbnails.remove(i);
6162                        N--;
6163                        continue;
6164                    }
6165                }
6166                i++;
6167            }
6168        }
6169
6170        if (receivers != null) {
6171            final int N = receivers.size();
6172            for (int i=0; i<N; i++) {
6173                try {
6174                    PendingThumbnailsRecord pr =
6175                        (PendingThumbnailsRecord)receivers.get(i);
6176                    pr.receiver.newThumbnail(
6177                        task != null ? task.taskId : -1, thumbnail, description);
6178                    if (pr.finished) {
6179                        pr.receiver.finished();
6180                    }
6181                } catch (Exception e) {
6182                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6183                }
6184            }
6185        }
6186    }
6187
6188    // =========================================================
6189    // CONTENT PROVIDERS
6190    // =========================================================
6191
6192    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6193        List<ProviderInfo> providers = null;
6194        try {
6195            providers = AppGlobals.getPackageManager().
6196                queryContentProviders(app.processName, app.uid,
6197                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6198        } catch (RemoteException ex) {
6199        }
6200        if (DEBUG_MU)
6201            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6202        int userId = app.userId;
6203        if (providers != null) {
6204            int N = providers.size();
6205            for (int i=0; i<N; i++) {
6206                ProviderInfo cpi =
6207                    (ProviderInfo)providers.get(i);
6208                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6209                        cpi.name, cpi.flags);
6210                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6211                    // This is a singleton provider, but a user besides the
6212                    // default user is asking to initialize a process it runs
6213                    // in...  well, no, it doesn't actually run in this process,
6214                    // it runs in the process of the default user.  Get rid of it.
6215                    providers.remove(i);
6216                    N--;
6217                    continue;
6218                }
6219
6220                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6221                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6222                if (cpr == null) {
6223                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6224                    mProviderMap.putProviderByClass(comp, cpr);
6225                }
6226                if (DEBUG_MU)
6227                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6228                app.pubProviders.put(cpi.name, cpr);
6229                app.addPackage(cpi.applicationInfo.packageName);
6230                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6231            }
6232        }
6233        return providers;
6234    }
6235
6236    /**
6237     * Check if {@link ProcessRecord} has a possible chance at accessing the
6238     * given {@link ProviderInfo}. Final permission checking is always done
6239     * in {@link ContentProvider}.
6240     */
6241    private final String checkContentProviderPermissionLocked(
6242            ProviderInfo cpi, ProcessRecord r) {
6243        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6244        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6245        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6246                cpi.applicationInfo.uid, cpi.exported)
6247                == PackageManager.PERMISSION_GRANTED) {
6248            return null;
6249        }
6250        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6251                cpi.applicationInfo.uid, cpi.exported)
6252                == PackageManager.PERMISSION_GRANTED) {
6253            return null;
6254        }
6255
6256        PathPermission[] pps = cpi.pathPermissions;
6257        if (pps != null) {
6258            int i = pps.length;
6259            while (i > 0) {
6260                i--;
6261                PathPermission pp = pps[i];
6262                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6263                        cpi.applicationInfo.uid, cpi.exported)
6264                        == PackageManager.PERMISSION_GRANTED) {
6265                    return null;
6266                }
6267                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6268                        cpi.applicationInfo.uid, cpi.exported)
6269                        == PackageManager.PERMISSION_GRANTED) {
6270                    return null;
6271                }
6272            }
6273        }
6274
6275        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6276        if (perms != null) {
6277            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6278                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6279                    return null;
6280                }
6281            }
6282        }
6283
6284        String msg;
6285        if (!cpi.exported) {
6286            msg = "Permission Denial: opening provider " + cpi.name
6287                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6288                    + ", uid=" + callingUid + ") that is not exported from uid "
6289                    + cpi.applicationInfo.uid;
6290        } else {
6291            msg = "Permission Denial: opening provider " + cpi.name
6292                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6293                    + ", uid=" + callingUid + ") requires "
6294                    + cpi.readPermission + " or " + cpi.writePermission;
6295        }
6296        Slog.w(TAG, msg);
6297        return msg;
6298    }
6299
6300    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6301            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6302        if (r != null) {
6303            for (int i=0; i<r.conProviders.size(); i++) {
6304                ContentProviderConnection conn = r.conProviders.get(i);
6305                if (conn.provider == cpr) {
6306                    if (DEBUG_PROVIDER) Slog.v(TAG,
6307                            "Adding provider requested by "
6308                            + r.processName + " from process "
6309                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6310                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6311                    if (stable) {
6312                        conn.stableCount++;
6313                        conn.numStableIncs++;
6314                    } else {
6315                        conn.unstableCount++;
6316                        conn.numUnstableIncs++;
6317                    }
6318                    return conn;
6319                }
6320            }
6321            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6322            if (stable) {
6323                conn.stableCount = 1;
6324                conn.numStableIncs = 1;
6325            } else {
6326                conn.unstableCount = 1;
6327                conn.numUnstableIncs = 1;
6328            }
6329            cpr.connections.add(conn);
6330            r.conProviders.add(conn);
6331            return conn;
6332        }
6333        cpr.addExternalProcessHandleLocked(externalProcessToken);
6334        return null;
6335    }
6336
6337    boolean decProviderCountLocked(ContentProviderConnection conn,
6338            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6339        if (conn != null) {
6340            cpr = conn.provider;
6341            if (DEBUG_PROVIDER) Slog.v(TAG,
6342                    "Removing provider requested by "
6343                    + conn.client.processName + " from process "
6344                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6345                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6346            if (stable) {
6347                conn.stableCount--;
6348            } else {
6349                conn.unstableCount--;
6350            }
6351            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6352                cpr.connections.remove(conn);
6353                conn.client.conProviders.remove(conn);
6354                return true;
6355            }
6356            return false;
6357        }
6358        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6359        return false;
6360    }
6361
6362    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6363            String name, IBinder token, boolean stable, int userId) {
6364        ContentProviderRecord cpr;
6365        ContentProviderConnection conn = null;
6366        ProviderInfo cpi = null;
6367
6368        synchronized(this) {
6369            ProcessRecord r = null;
6370            if (caller != null) {
6371                r = getRecordForAppLocked(caller);
6372                if (r == null) {
6373                    throw new SecurityException(
6374                            "Unable to find app for caller " + caller
6375                          + " (pid=" + Binder.getCallingPid()
6376                          + ") when getting content provider " + name);
6377                }
6378            }
6379
6380            // First check if this content provider has been published...
6381            cpr = mProviderMap.getProviderByName(name, userId);
6382            boolean providerRunning = cpr != null;
6383            if (providerRunning) {
6384                cpi = cpr.info;
6385                String msg;
6386                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6387                    throw new SecurityException(msg);
6388                }
6389
6390                if (r != null && cpr.canRunHere(r)) {
6391                    // This provider has been published or is in the process
6392                    // of being published...  but it is also allowed to run
6393                    // in the caller's process, so don't make a connection
6394                    // and just let the caller instantiate its own instance.
6395                    ContentProviderHolder holder = cpr.newHolder(null);
6396                    // don't give caller the provider object, it needs
6397                    // to make its own.
6398                    holder.provider = null;
6399                    return holder;
6400                }
6401
6402                final long origId = Binder.clearCallingIdentity();
6403
6404                // In this case the provider instance already exists, so we can
6405                // return it right away.
6406                conn = incProviderCountLocked(r, cpr, token, stable);
6407                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6408                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6409                        // If this is a perceptible app accessing the provider,
6410                        // make sure to count it as being accessed and thus
6411                        // back up on the LRU list.  This is good because
6412                        // content providers are often expensive to start.
6413                        updateLruProcessLocked(cpr.proc, false);
6414                    }
6415                }
6416
6417                if (cpr.proc != null) {
6418                    if (false) {
6419                        if (cpr.name.flattenToShortString().equals(
6420                                "com.android.providers.calendar/.CalendarProvider2")) {
6421                            Slog.v(TAG, "****************** KILLING "
6422                                + cpr.name.flattenToShortString());
6423                            Process.killProcess(cpr.proc.pid);
6424                        }
6425                    }
6426                    boolean success = updateOomAdjLocked(cpr.proc);
6427                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6428                    // NOTE: there is still a race here where a signal could be
6429                    // pending on the process even though we managed to update its
6430                    // adj level.  Not sure what to do about this, but at least
6431                    // the race is now smaller.
6432                    if (!success) {
6433                        // Uh oh...  it looks like the provider's process
6434                        // has been killed on us.  We need to wait for a new
6435                        // process to be started, and make sure its death
6436                        // doesn't kill our process.
6437                        Slog.i(TAG,
6438                                "Existing provider " + cpr.name.flattenToShortString()
6439                                + " is crashing; detaching " + r);
6440                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6441                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6442                        if (!lastRef) {
6443                            // This wasn't the last ref our process had on
6444                            // the provider...  we have now been killed, bail.
6445                            return null;
6446                        }
6447                        providerRunning = false;
6448                        conn = null;
6449                    }
6450                }
6451
6452                Binder.restoreCallingIdentity(origId);
6453            }
6454
6455            boolean singleton;
6456            if (!providerRunning) {
6457                try {
6458                    cpi = AppGlobals.getPackageManager().
6459                        resolveContentProvider(name,
6460                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6461                } catch (RemoteException ex) {
6462                }
6463                if (cpi == null) {
6464                    return null;
6465                }
6466                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6467                        cpi.name, cpi.flags);
6468                if (singleton) {
6469                    userId = 0;
6470                }
6471                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6472
6473                String msg;
6474                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6475                    throw new SecurityException(msg);
6476                }
6477
6478                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6479                        && !cpi.processName.equals("system")) {
6480                    // If this content provider does not run in the system
6481                    // process, and the system is not yet ready to run other
6482                    // processes, then fail fast instead of hanging.
6483                    throw new IllegalArgumentException(
6484                            "Attempt to launch content provider before system ready");
6485                }
6486
6487                // Make sure that the user who owns this provider is started.  If not,
6488                // we don't want to allow it to run.
6489                if (mStartedUsers.get(userId) == null) {
6490                    Slog.w(TAG, "Unable to launch app "
6491                            + cpi.applicationInfo.packageName + "/"
6492                            + cpi.applicationInfo.uid + " for provider "
6493                            + name + ": user " + userId + " is stopped");
6494                    return null;
6495                }
6496
6497                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6498                cpr = mProviderMap.getProviderByClass(comp, userId);
6499                final boolean firstClass = cpr == null;
6500                if (firstClass) {
6501                    try {
6502                        ApplicationInfo ai =
6503                            AppGlobals.getPackageManager().
6504                                getApplicationInfo(
6505                                        cpi.applicationInfo.packageName,
6506                                        STOCK_PM_FLAGS, userId);
6507                        if (ai == null) {
6508                            Slog.w(TAG, "No package info for content provider "
6509                                    + cpi.name);
6510                            return null;
6511                        }
6512                        ai = getAppInfoForUser(ai, userId);
6513                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6514                    } catch (RemoteException ex) {
6515                        // pm is in same process, this will never happen.
6516                    }
6517                }
6518
6519                if (r != null && cpr.canRunHere(r)) {
6520                    // If this is a multiprocess provider, then just return its
6521                    // info and allow the caller to instantiate it.  Only do
6522                    // this if the provider is the same user as the caller's
6523                    // process, or can run as root (so can be in any process).
6524                    return cpr.newHolder(null);
6525                }
6526
6527                if (DEBUG_PROVIDER) {
6528                    RuntimeException e = new RuntimeException("here");
6529                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6530                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6531                }
6532
6533                // This is single process, and our app is now connecting to it.
6534                // See if we are already in the process of launching this
6535                // provider.
6536                final int N = mLaunchingProviders.size();
6537                int i;
6538                for (i=0; i<N; i++) {
6539                    if (mLaunchingProviders.get(i) == cpr) {
6540                        break;
6541                    }
6542                }
6543
6544                // If the provider is not already being launched, then get it
6545                // started.
6546                if (i >= N) {
6547                    final long origId = Binder.clearCallingIdentity();
6548
6549                    try {
6550                        // Content provider is now in use, its package can't be stopped.
6551                        try {
6552                            AppGlobals.getPackageManager().setPackageStoppedState(
6553                                    cpr.appInfo.packageName, false, userId);
6554                        } catch (RemoteException e) {
6555                        } catch (IllegalArgumentException e) {
6556                            Slog.w(TAG, "Failed trying to unstop package "
6557                                    + cpr.appInfo.packageName + ": " + e);
6558                        }
6559
6560                        ProcessRecord proc = startProcessLocked(cpi.processName,
6561                                cpr.appInfo, false, 0, "content provider",
6562                                new ComponentName(cpi.applicationInfo.packageName,
6563                                        cpi.name), false, false);
6564                        if (proc == null) {
6565                            Slog.w(TAG, "Unable to launch app "
6566                                    + cpi.applicationInfo.packageName + "/"
6567                                    + cpi.applicationInfo.uid + " for provider "
6568                                    + name + ": process is bad");
6569                            return null;
6570                        }
6571                        cpr.launchingApp = proc;
6572                        mLaunchingProviders.add(cpr);
6573                    } finally {
6574                        Binder.restoreCallingIdentity(origId);
6575                    }
6576                }
6577
6578                // Make sure the provider is published (the same provider class
6579                // may be published under multiple names).
6580                if (firstClass) {
6581                    mProviderMap.putProviderByClass(comp, cpr);
6582                }
6583
6584                mProviderMap.putProviderByName(name, cpr);
6585                conn = incProviderCountLocked(r, cpr, token, stable);
6586                if (conn != null) {
6587                    conn.waiting = true;
6588                }
6589            }
6590        }
6591
6592        // Wait for the provider to be published...
6593        synchronized (cpr) {
6594            while (cpr.provider == null) {
6595                if (cpr.launchingApp == null) {
6596                    Slog.w(TAG, "Unable to launch app "
6597                            + cpi.applicationInfo.packageName + "/"
6598                            + cpi.applicationInfo.uid + " for provider "
6599                            + name + ": launching app became null");
6600                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6601                            UserHandle.getUserId(cpi.applicationInfo.uid),
6602                            cpi.applicationInfo.packageName,
6603                            cpi.applicationInfo.uid, name);
6604                    return null;
6605                }
6606                try {
6607                    if (DEBUG_MU) {
6608                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6609                                + cpr.launchingApp);
6610                    }
6611                    if (conn != null) {
6612                        conn.waiting = true;
6613                    }
6614                    cpr.wait();
6615                } catch (InterruptedException ex) {
6616                } finally {
6617                    if (conn != null) {
6618                        conn.waiting = false;
6619                    }
6620                }
6621            }
6622        }
6623        return cpr != null ? cpr.newHolder(conn) : null;
6624    }
6625
6626    public final ContentProviderHolder getContentProvider(
6627            IApplicationThread caller, String name, int userId, boolean stable) {
6628        enforceNotIsolatedCaller("getContentProvider");
6629        if (caller == null) {
6630            String msg = "null IApplicationThread when getting content provider "
6631                    + name;
6632            Slog.w(TAG, msg);
6633            throw new SecurityException(msg);
6634        }
6635
6636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6637                false, true, "getContentProvider", null);
6638        return getContentProviderImpl(caller, name, null, stable, userId);
6639    }
6640
6641    public ContentProviderHolder getContentProviderExternal(
6642            String name, int userId, IBinder token) {
6643        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6644            "Do not have permission in call getContentProviderExternal()");
6645        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6646                false, true, "getContentProvider", null);
6647        return getContentProviderExternalUnchecked(name, token, userId);
6648    }
6649
6650    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6651            IBinder token, int userId) {
6652        return getContentProviderImpl(null, name, token, true, userId);
6653    }
6654
6655    /**
6656     * Drop a content provider from a ProcessRecord's bookkeeping
6657     * @param cpr
6658     */
6659    public void removeContentProvider(IBinder connection, boolean stable) {
6660        enforceNotIsolatedCaller("removeContentProvider");
6661        synchronized (this) {
6662            ContentProviderConnection conn;
6663            try {
6664                conn = (ContentProviderConnection)connection;
6665            } catch (ClassCastException e) {
6666                String msg ="removeContentProvider: " + connection
6667                        + " not a ContentProviderConnection";
6668                Slog.w(TAG, msg);
6669                throw new IllegalArgumentException(msg);
6670            }
6671            if (conn == null) {
6672                throw new NullPointerException("connection is null");
6673            }
6674            if (decProviderCountLocked(conn, null, null, stable)) {
6675                updateOomAdjLocked();
6676            }
6677        }
6678    }
6679
6680    public void removeContentProviderExternal(String name, IBinder token) {
6681        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6682            "Do not have permission in call removeContentProviderExternal()");
6683        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6684    }
6685
6686    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6687        synchronized (this) {
6688            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6689            if(cpr == null) {
6690                //remove from mProvidersByClass
6691                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6692                return;
6693            }
6694
6695            //update content provider record entry info
6696            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6697            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6698            if (localCpr.hasExternalProcessHandles()) {
6699                if (localCpr.removeExternalProcessHandleLocked(token)) {
6700                    updateOomAdjLocked();
6701                } else {
6702                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6703                            + " with no external reference for token: "
6704                            + token + ".");
6705                }
6706            } else {
6707                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6708                        + " with no external references.");
6709            }
6710        }
6711    }
6712
6713    public final void publishContentProviders(IApplicationThread caller,
6714            List<ContentProviderHolder> providers) {
6715        if (providers == null) {
6716            return;
6717        }
6718
6719        enforceNotIsolatedCaller("publishContentProviders");
6720        synchronized (this) {
6721            final ProcessRecord r = getRecordForAppLocked(caller);
6722            if (DEBUG_MU)
6723                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6724            if (r == null) {
6725                throw new SecurityException(
6726                        "Unable to find app for caller " + caller
6727                      + " (pid=" + Binder.getCallingPid()
6728                      + ") when publishing content providers");
6729            }
6730
6731            final long origId = Binder.clearCallingIdentity();
6732
6733            final int N = providers.size();
6734            for (int i=0; i<N; i++) {
6735                ContentProviderHolder src = providers.get(i);
6736                if (src == null || src.info == null || src.provider == null) {
6737                    continue;
6738                }
6739                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6740                if (DEBUG_MU)
6741                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6742                if (dst != null) {
6743                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6744                    mProviderMap.putProviderByClass(comp, dst);
6745                    String names[] = dst.info.authority.split(";");
6746                    for (int j = 0; j < names.length; j++) {
6747                        mProviderMap.putProviderByName(names[j], dst);
6748                    }
6749
6750                    int NL = mLaunchingProviders.size();
6751                    int j;
6752                    for (j=0; j<NL; j++) {
6753                        if (mLaunchingProviders.get(j) == dst) {
6754                            mLaunchingProviders.remove(j);
6755                            j--;
6756                            NL--;
6757                        }
6758                    }
6759                    synchronized (dst) {
6760                        dst.provider = src.provider;
6761                        dst.proc = r;
6762                        dst.notifyAll();
6763                    }
6764                    updateOomAdjLocked(r);
6765                }
6766            }
6767
6768            Binder.restoreCallingIdentity(origId);
6769        }
6770    }
6771
6772    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6773        ContentProviderConnection conn;
6774        try {
6775            conn = (ContentProviderConnection)connection;
6776        } catch (ClassCastException e) {
6777            String msg ="refContentProvider: " + connection
6778                    + " not a ContentProviderConnection";
6779            Slog.w(TAG, msg);
6780            throw new IllegalArgumentException(msg);
6781        }
6782        if (conn == null) {
6783            throw new NullPointerException("connection is null");
6784        }
6785
6786        synchronized (this) {
6787            if (stable > 0) {
6788                conn.numStableIncs += stable;
6789            }
6790            stable = conn.stableCount + stable;
6791            if (stable < 0) {
6792                throw new IllegalStateException("stableCount < 0: " + stable);
6793            }
6794
6795            if (unstable > 0) {
6796                conn.numUnstableIncs += unstable;
6797            }
6798            unstable = conn.unstableCount + unstable;
6799            if (unstable < 0) {
6800                throw new IllegalStateException("unstableCount < 0: " + unstable);
6801            }
6802
6803            if ((stable+unstable) <= 0) {
6804                throw new IllegalStateException("ref counts can't go to zero here: stable="
6805                        + stable + " unstable=" + unstable);
6806            }
6807            conn.stableCount = stable;
6808            conn.unstableCount = unstable;
6809            return !conn.dead;
6810        }
6811    }
6812
6813    public void unstableProviderDied(IBinder connection) {
6814        ContentProviderConnection conn;
6815        try {
6816            conn = (ContentProviderConnection)connection;
6817        } catch (ClassCastException e) {
6818            String msg ="refContentProvider: " + connection
6819                    + " not a ContentProviderConnection";
6820            Slog.w(TAG, msg);
6821            throw new IllegalArgumentException(msg);
6822        }
6823        if (conn == null) {
6824            throw new NullPointerException("connection is null");
6825        }
6826
6827        // Safely retrieve the content provider associated with the connection.
6828        IContentProvider provider;
6829        synchronized (this) {
6830            provider = conn.provider.provider;
6831        }
6832
6833        if (provider == null) {
6834            // Um, yeah, we're way ahead of you.
6835            return;
6836        }
6837
6838        // Make sure the caller is being honest with us.
6839        if (provider.asBinder().pingBinder()) {
6840            // Er, no, still looks good to us.
6841            synchronized (this) {
6842                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6843                        + " says " + conn + " died, but we don't agree");
6844                return;
6845            }
6846        }
6847
6848        // Well look at that!  It's dead!
6849        synchronized (this) {
6850            if (conn.provider.provider != provider) {
6851                // But something changed...  good enough.
6852                return;
6853            }
6854
6855            ProcessRecord proc = conn.provider.proc;
6856            if (proc == null || proc.thread == null) {
6857                // Seems like the process is already cleaned up.
6858                return;
6859            }
6860
6861            // As far as we're concerned, this is just like receiving a
6862            // death notification...  just a bit prematurely.
6863            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6864                    + ") early provider death");
6865            final long ident = Binder.clearCallingIdentity();
6866            try {
6867                appDiedLocked(proc, proc.pid, proc.thread);
6868            } finally {
6869                Binder.restoreCallingIdentity(ident);
6870            }
6871        }
6872    }
6873
6874    public static final void installSystemProviders() {
6875        List<ProviderInfo> providers;
6876        synchronized (mSelf) {
6877            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6878            providers = mSelf.generateApplicationProvidersLocked(app);
6879            if (providers != null) {
6880                for (int i=providers.size()-1; i>=0; i--) {
6881                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6882                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6883                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6884                                + ": not system .apk");
6885                        providers.remove(i);
6886                    }
6887                }
6888            }
6889        }
6890        if (providers != null) {
6891            mSystemThread.installSystemProviders(providers);
6892        }
6893
6894        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6895
6896        mSelf.mUsageStatsService.monitorPackages();
6897    }
6898
6899    /**
6900     * Allows app to retrieve the MIME type of a URI without having permission
6901     * to access its content provider.
6902     *
6903     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6904     *
6905     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6906     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6907     */
6908    public String getProviderMimeType(Uri uri, int userId) {
6909        enforceNotIsolatedCaller("getProviderMimeType");
6910        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6911                userId, false, true, "getProviderMimeType", null);
6912        final String name = uri.getAuthority();
6913        final long ident = Binder.clearCallingIdentity();
6914        ContentProviderHolder holder = null;
6915
6916        try {
6917            holder = getContentProviderExternalUnchecked(name, null, userId);
6918            if (holder != null) {
6919                return holder.provider.getType(uri);
6920            }
6921        } catch (RemoteException e) {
6922            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6923            return null;
6924        } finally {
6925            if (holder != null) {
6926                removeContentProviderExternalUnchecked(name, null, userId);
6927            }
6928            Binder.restoreCallingIdentity(ident);
6929        }
6930
6931        return null;
6932    }
6933
6934    // =========================================================
6935    // GLOBAL MANAGEMENT
6936    // =========================================================
6937
6938    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6939            ApplicationInfo info, String customProcess, boolean isolated) {
6940        String proc = customProcess != null ? customProcess : info.processName;
6941        BatteryStatsImpl.Uid.Proc ps = null;
6942        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6943        int uid = info.uid;
6944        if (isolated) {
6945            int userId = UserHandle.getUserId(uid);
6946            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6947            uid = 0;
6948            while (true) {
6949                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6950                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6951                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6952                }
6953                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6954                mNextIsolatedProcessUid++;
6955                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6956                    // No process for this uid, use it.
6957                    break;
6958                }
6959                stepsLeft--;
6960                if (stepsLeft <= 0) {
6961                    return null;
6962                }
6963            }
6964        }
6965        synchronized (stats) {
6966            ps = stats.getProcessStatsLocked(info.uid, proc);
6967        }
6968        return new ProcessRecord(ps, thread, info, proc, uid);
6969    }
6970
6971    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6972        ProcessRecord app;
6973        if (!isolated) {
6974            app = getProcessRecordLocked(info.processName, info.uid);
6975        } else {
6976            app = null;
6977        }
6978
6979        if (app == null) {
6980            app = newProcessRecordLocked(null, info, null, isolated);
6981            mProcessNames.put(info.processName, app.uid, app);
6982            if (isolated) {
6983                mIsolatedProcesses.put(app.uid, app);
6984            }
6985            updateLruProcessLocked(app, true);
6986        }
6987
6988        // This package really, really can not be stopped.
6989        try {
6990            AppGlobals.getPackageManager().setPackageStoppedState(
6991                    info.packageName, false, UserHandle.getUserId(app.uid));
6992        } catch (RemoteException e) {
6993        } catch (IllegalArgumentException e) {
6994            Slog.w(TAG, "Failed trying to unstop package "
6995                    + info.packageName + ": " + e);
6996        }
6997
6998        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6999                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7000            app.persistent = true;
7001            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7002        }
7003        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7004            mPersistentStartingProcesses.add(app);
7005            startProcessLocked(app, "added application", app.processName);
7006        }
7007
7008        return app;
7009    }
7010
7011    public void unhandledBack() {
7012        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7013                "unhandledBack()");
7014
7015        synchronized(this) {
7016            int count = mMainStack.mHistory.size();
7017            if (DEBUG_SWITCH) Slog.d(
7018                TAG, "Performing unhandledBack(): stack size = " + count);
7019            if (count > 1) {
7020                final long origId = Binder.clearCallingIdentity();
7021                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7022                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7023                Binder.restoreCallingIdentity(origId);
7024            }
7025        }
7026    }
7027
7028    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7029        enforceNotIsolatedCaller("openContentUri");
7030        final int userId = UserHandle.getCallingUserId();
7031        String name = uri.getAuthority();
7032        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7033        ParcelFileDescriptor pfd = null;
7034        if (cph != null) {
7035            // We record the binder invoker's uid in thread-local storage before
7036            // going to the content provider to open the file.  Later, in the code
7037            // that handles all permissions checks, we look for this uid and use
7038            // that rather than the Activity Manager's own uid.  The effect is that
7039            // we do the check against the caller's permissions even though it looks
7040            // to the content provider like the Activity Manager itself is making
7041            // the request.
7042            sCallerIdentity.set(new Identity(
7043                    Binder.getCallingPid(), Binder.getCallingUid()));
7044            try {
7045                pfd = cph.provider.openFile(uri, "r");
7046            } catch (FileNotFoundException e) {
7047                // do nothing; pfd will be returned null
7048            } finally {
7049                // Ensure that whatever happens, we clean up the identity state
7050                sCallerIdentity.remove();
7051            }
7052
7053            // We've got the fd now, so we're done with the provider.
7054            removeContentProviderExternalUnchecked(name, null, userId);
7055        } else {
7056            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7057        }
7058        return pfd;
7059    }
7060
7061    // Actually is sleeping or shutting down or whatever else in the future
7062    // is an inactive state.
7063    public boolean isSleeping() {
7064        return mSleeping || mShuttingDown;
7065    }
7066
7067    public void goingToSleep() {
7068        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7069                != PackageManager.PERMISSION_GRANTED) {
7070            throw new SecurityException("Requires permission "
7071                    + android.Manifest.permission.DEVICE_POWER);
7072        }
7073
7074        synchronized(this) {
7075            mWentToSleep = true;
7076            updateEventDispatchingLocked();
7077
7078            if (!mSleeping) {
7079                mSleeping = true;
7080                mMainStack.stopIfSleepingLocked();
7081
7082                // Initialize the wake times of all processes.
7083                checkExcessivePowerUsageLocked(false);
7084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7087            }
7088        }
7089    }
7090
7091    public boolean shutdown(int timeout) {
7092        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7093                != PackageManager.PERMISSION_GRANTED) {
7094            throw new SecurityException("Requires permission "
7095                    + android.Manifest.permission.SHUTDOWN);
7096        }
7097
7098        boolean timedout = false;
7099
7100        synchronized(this) {
7101            mShuttingDown = true;
7102            updateEventDispatchingLocked();
7103
7104            if (mMainStack.mResumedActivity != null) {
7105                mMainStack.stopIfSleepingLocked();
7106                final long endTime = System.currentTimeMillis() + timeout;
7107                while (mMainStack.mResumedActivity != null
7108                        || mMainStack.mPausingActivity != null) {
7109                    long delay = endTime - System.currentTimeMillis();
7110                    if (delay <= 0) {
7111                        Slog.w(TAG, "Activity manager shutdown timed out");
7112                        timedout = true;
7113                        break;
7114                    }
7115                    try {
7116                        this.wait();
7117                    } catch (InterruptedException e) {
7118                    }
7119                }
7120            }
7121        }
7122
7123        mUsageStatsService.shutdown();
7124        mBatteryStatsService.shutdown();
7125
7126        return timedout;
7127    }
7128
7129    public final void activitySlept(IBinder token) {
7130        if (localLOGV) Slog.v(
7131            TAG, "Activity slept: token=" + token);
7132
7133        ActivityRecord r = null;
7134
7135        final long origId = Binder.clearCallingIdentity();
7136
7137        synchronized (this) {
7138            r = mMainStack.isInStackLocked(token);
7139            if (r != null) {
7140                mMainStack.activitySleptLocked(r);
7141            }
7142        }
7143
7144        Binder.restoreCallingIdentity(origId);
7145    }
7146
7147    private void comeOutOfSleepIfNeededLocked() {
7148        if (!mWentToSleep && !mLockScreenShown) {
7149            if (mSleeping) {
7150                mSleeping = false;
7151                mMainStack.awakeFromSleepingLocked();
7152                mMainStack.resumeTopActivityLocked(null);
7153            }
7154        }
7155    }
7156
7157    public void wakingUp() {
7158        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7159                != PackageManager.PERMISSION_GRANTED) {
7160            throw new SecurityException("Requires permission "
7161                    + android.Manifest.permission.DEVICE_POWER);
7162        }
7163
7164        synchronized(this) {
7165            mWentToSleep = false;
7166            updateEventDispatchingLocked();
7167            comeOutOfSleepIfNeededLocked();
7168        }
7169    }
7170
7171    private void updateEventDispatchingLocked() {
7172        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7173    }
7174
7175    public void setLockScreenShown(boolean shown) {
7176        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7177                != PackageManager.PERMISSION_GRANTED) {
7178            throw new SecurityException("Requires permission "
7179                    + android.Manifest.permission.DEVICE_POWER);
7180        }
7181
7182        synchronized(this) {
7183            mLockScreenShown = shown;
7184            comeOutOfSleepIfNeededLocked();
7185        }
7186    }
7187
7188    public void stopAppSwitches() {
7189        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7190                != PackageManager.PERMISSION_GRANTED) {
7191            throw new SecurityException("Requires permission "
7192                    + android.Manifest.permission.STOP_APP_SWITCHES);
7193        }
7194
7195        synchronized(this) {
7196            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7197                    + APP_SWITCH_DELAY_TIME;
7198            mDidAppSwitch = false;
7199            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7200            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7201            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7202        }
7203    }
7204
7205    public void resumeAppSwitches() {
7206        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7207                != PackageManager.PERMISSION_GRANTED) {
7208            throw new SecurityException("Requires permission "
7209                    + android.Manifest.permission.STOP_APP_SWITCHES);
7210        }
7211
7212        synchronized(this) {
7213            // Note that we don't execute any pending app switches... we will
7214            // let those wait until either the timeout, or the next start
7215            // activity request.
7216            mAppSwitchesAllowedTime = 0;
7217        }
7218    }
7219
7220    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7221            String name) {
7222        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7223            return true;
7224        }
7225
7226        final int perm = checkComponentPermission(
7227                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7228                callingUid, -1, true);
7229        if (perm == PackageManager.PERMISSION_GRANTED) {
7230            return true;
7231        }
7232
7233        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7234        return false;
7235    }
7236
7237    public void setDebugApp(String packageName, boolean waitForDebugger,
7238            boolean persistent) {
7239        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7240                "setDebugApp()");
7241
7242        // Note that this is not really thread safe if there are multiple
7243        // callers into it at the same time, but that's not a situation we
7244        // care about.
7245        if (persistent) {
7246            final ContentResolver resolver = mContext.getContentResolver();
7247            Settings.System.putString(
7248                resolver, Settings.System.DEBUG_APP,
7249                packageName);
7250            Settings.System.putInt(
7251                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7252                waitForDebugger ? 1 : 0);
7253        }
7254
7255        synchronized (this) {
7256            if (!persistent) {
7257                mOrigDebugApp = mDebugApp;
7258                mOrigWaitForDebugger = mWaitForDebugger;
7259            }
7260            mDebugApp = packageName;
7261            mWaitForDebugger = waitForDebugger;
7262            mDebugTransient = !persistent;
7263            if (packageName != null) {
7264                final long origId = Binder.clearCallingIdentity();
7265                forceStopPackageLocked(packageName, -1, false, false, true, true,
7266                        UserHandle.USER_ALL);
7267                Binder.restoreCallingIdentity(origId);
7268            }
7269        }
7270    }
7271
7272    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7273        synchronized (this) {
7274            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7275            if (!isDebuggable) {
7276                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7277                    throw new SecurityException("Process not debuggable: " + app.packageName);
7278                }
7279            }
7280
7281            mOpenGlTraceApp = processName;
7282        }
7283    }
7284
7285    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7286            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7287        synchronized (this) {
7288            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7289            if (!isDebuggable) {
7290                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7291                    throw new SecurityException("Process not debuggable: " + app.packageName);
7292                }
7293            }
7294            mProfileApp = processName;
7295            mProfileFile = profileFile;
7296            if (mProfileFd != null) {
7297                try {
7298                    mProfileFd.close();
7299                } catch (IOException e) {
7300                }
7301                mProfileFd = null;
7302            }
7303            mProfileFd = profileFd;
7304            mProfileType = 0;
7305            mAutoStopProfiler = autoStopProfiler;
7306        }
7307    }
7308
7309    public void setAlwaysFinish(boolean enabled) {
7310        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7311                "setAlwaysFinish()");
7312
7313        Settings.System.putInt(
7314                mContext.getContentResolver(),
7315                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7316
7317        synchronized (this) {
7318            mAlwaysFinishActivities = enabled;
7319        }
7320    }
7321
7322    public void setActivityController(IActivityController controller) {
7323        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7324                "setActivityController()");
7325        synchronized (this) {
7326            mController = controller;
7327        }
7328    }
7329
7330    public boolean isUserAMonkey() {
7331        // For now the fact that there is a controller implies
7332        // we have a monkey.
7333        synchronized (this) {
7334            return mController != null;
7335        }
7336    }
7337
7338    public void requestBugReport() {
7339        // No permission check because this can't do anything harmful --
7340        // it will just eventually cause the user to be presented with
7341        // a UI to select where the bug report goes.
7342        SystemProperties.set("ctl.start", "bugreport");
7343    }
7344
7345    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7346        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7347                != PackageManager.PERMISSION_GRANTED) {
7348            throw new SecurityException("Requires permission "
7349                    + android.Manifest.permission.FILTER_EVENTS);
7350        }
7351
7352        ProcessRecord proc;
7353
7354        // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7355        synchronized (this) {
7356            synchronized (mPidsSelfLocked) {
7357                proc = mPidsSelfLocked.get(pid);
7358            }
7359            if (proc != null) {
7360                if (proc.debugging) {
7361                    return -1;
7362                }
7363
7364                if (mDidDexOpt) {
7365                    // Give more time since we were dexopting.
7366                    mDidDexOpt = false;
7367                    return -1;
7368                }
7369
7370                if (proc.instrumentationClass != null) {
7371                    Bundle info = new Bundle();
7372                    info.putString("shortMsg", "keyDispatchingTimedOut");
7373                    info.putString("longMsg", "Timed out while dispatching key event");
7374                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7375                    proc = null;
7376                }
7377            }
7378        }
7379
7380        if (proc != null) {
7381            appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7382            if (proc.instrumentationClass != null || proc.usingWrapper) {
7383                return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7384            }
7385        }
7386
7387        return KEY_DISPATCHING_TIMEOUT;
7388    }
7389
7390    public void registerProcessObserver(IProcessObserver observer) {
7391        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7392                "registerProcessObserver()");
7393        synchronized (this) {
7394            mProcessObservers.register(observer);
7395        }
7396    }
7397
7398    public void unregisterProcessObserver(IProcessObserver observer) {
7399        synchronized (this) {
7400            mProcessObservers.unregister(observer);
7401        }
7402    }
7403
7404    public void setImmersive(IBinder token, boolean immersive) {
7405        synchronized(this) {
7406            ActivityRecord r = mMainStack.isInStackLocked(token);
7407            if (r == null) {
7408                throw new IllegalArgumentException();
7409            }
7410            r.immersive = immersive;
7411        }
7412    }
7413
7414    public boolean isImmersive(IBinder token) {
7415        synchronized (this) {
7416            ActivityRecord r = mMainStack.isInStackLocked(token);
7417            if (r == null) {
7418                throw new IllegalArgumentException();
7419            }
7420            return r.immersive;
7421        }
7422    }
7423
7424    public boolean isTopActivityImmersive() {
7425        enforceNotIsolatedCaller("startActivity");
7426        synchronized (this) {
7427            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7428            return (r != null) ? r.immersive : false;
7429        }
7430    }
7431
7432    public final void enterSafeMode() {
7433        synchronized(this) {
7434            // It only makes sense to do this before the system is ready
7435            // and started launching other packages.
7436            if (!mSystemReady) {
7437                try {
7438                    AppGlobals.getPackageManager().enterSafeMode();
7439                } catch (RemoteException e) {
7440                }
7441            }
7442        }
7443    }
7444
7445    public final void showSafeModeOverlay() {
7446        View v = LayoutInflater.from(mContext).inflate(
7447                com.android.internal.R.layout.safe_mode, null);
7448        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7449        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7450        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7451        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7452        lp.gravity = Gravity.BOTTOM | Gravity.START;
7453        lp.format = v.getBackground().getOpacity();
7454        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7455                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7456        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7457        ((WindowManager)mContext.getSystemService(
7458                Context.WINDOW_SERVICE)).addView(v, lp);
7459    }
7460
7461    public void noteWakeupAlarm(IIntentSender sender) {
7462        if (!(sender instanceof PendingIntentRecord)) {
7463            return;
7464        }
7465        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7466        synchronized (stats) {
7467            if (mBatteryStatsService.isOnBattery()) {
7468                mBatteryStatsService.enforceCallingPermission();
7469                PendingIntentRecord rec = (PendingIntentRecord)sender;
7470                int MY_UID = Binder.getCallingUid();
7471                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7472                BatteryStatsImpl.Uid.Pkg pkg =
7473                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7474                pkg.incWakeupsLocked();
7475            }
7476        }
7477    }
7478
7479    public boolean killPids(int[] pids, String pReason, boolean secure) {
7480        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7481            throw new SecurityException("killPids only available to the system");
7482        }
7483        String reason = (pReason == null) ? "Unknown" : pReason;
7484        // XXX Note: don't acquire main activity lock here, because the window
7485        // manager calls in with its locks held.
7486
7487        boolean killed = false;
7488        synchronized (mPidsSelfLocked) {
7489            int[] types = new int[pids.length];
7490            int worstType = 0;
7491            for (int i=0; i<pids.length; i++) {
7492                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7493                if (proc != null) {
7494                    int type = proc.setAdj;
7495                    types[i] = type;
7496                    if (type > worstType) {
7497                        worstType = type;
7498                    }
7499                }
7500            }
7501
7502            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7503            // then constrain it so we will kill all hidden procs.
7504            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7505                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7506                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7507            }
7508
7509            // If this is not a secure call, don't let it kill processes that
7510            // are important.
7511            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7512                worstType = ProcessList.SERVICE_ADJ;
7513            }
7514
7515            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7516            for (int i=0; i<pids.length; i++) {
7517                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7518                if (proc == null) {
7519                    continue;
7520                }
7521                int adj = proc.setAdj;
7522                if (adj >= worstType && !proc.killedBackground) {
7523                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7524                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7525                            proc.processName, adj, reason);
7526                    killed = true;
7527                    proc.killedBackground = true;
7528                    Process.killProcessQuiet(pids[i]);
7529                }
7530            }
7531        }
7532        return killed;
7533    }
7534
7535    @Override
7536    public boolean killProcessesBelowForeground(String reason) {
7537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7538            throw new SecurityException("killProcessesBelowForeground() only available to system");
7539        }
7540
7541        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7542    }
7543
7544    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7546            throw new SecurityException("killProcessesBelowAdj() only available to system");
7547        }
7548
7549        boolean killed = false;
7550        synchronized (mPidsSelfLocked) {
7551            final int size = mPidsSelfLocked.size();
7552            for (int i = 0; i < size; i++) {
7553                final int pid = mPidsSelfLocked.keyAt(i);
7554                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7555                if (proc == null) continue;
7556
7557                final int adj = proc.setAdj;
7558                if (adj > belowAdj && !proc.killedBackground) {
7559                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7560                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7561                            proc.pid, proc.processName, adj, reason);
7562                    killed = true;
7563                    proc.killedBackground = true;
7564                    Process.killProcessQuiet(pid);
7565                }
7566            }
7567        }
7568        return killed;
7569    }
7570
7571    public final void startRunning(String pkg, String cls, String action,
7572            String data) {
7573        synchronized(this) {
7574            if (mStartRunning) {
7575                return;
7576            }
7577            mStartRunning = true;
7578            mTopComponent = pkg != null && cls != null
7579                    ? new ComponentName(pkg, cls) : null;
7580            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7581            mTopData = data;
7582            if (!mSystemReady) {
7583                return;
7584            }
7585        }
7586
7587        systemReady(null);
7588    }
7589
7590    private void retrieveSettings() {
7591        final ContentResolver resolver = mContext.getContentResolver();
7592        String debugApp = Settings.System.getString(
7593            resolver, Settings.System.DEBUG_APP);
7594        boolean waitForDebugger = Settings.System.getInt(
7595            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7596        boolean alwaysFinishActivities = Settings.System.getInt(
7597            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7598
7599        Configuration configuration = new Configuration();
7600        Settings.System.getConfiguration(resolver, configuration);
7601
7602        synchronized (this) {
7603            mDebugApp = mOrigDebugApp = debugApp;
7604            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7605            mAlwaysFinishActivities = alwaysFinishActivities;
7606            // This happens before any activities are started, so we can
7607            // change mConfiguration in-place.
7608            updateConfigurationLocked(configuration, null, false, true);
7609            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7610        }
7611    }
7612
7613    public boolean testIsSystemReady() {
7614        // no need to synchronize(this) just to read & return the value
7615        return mSystemReady;
7616    }
7617
7618    private static File getCalledPreBootReceiversFile() {
7619        File dataDir = Environment.getDataDirectory();
7620        File systemDir = new File(dataDir, "system");
7621        File fname = new File(systemDir, "called_pre_boots.dat");
7622        return fname;
7623    }
7624
7625    static final int LAST_DONE_VERSION = 10000;
7626
7627    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7628        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7629        File file = getCalledPreBootReceiversFile();
7630        FileInputStream fis = null;
7631        try {
7632            fis = new FileInputStream(file);
7633            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7634            int fvers = dis.readInt();
7635            if (fvers == LAST_DONE_VERSION) {
7636                String vers = dis.readUTF();
7637                String codename = dis.readUTF();
7638                String build = dis.readUTF();
7639                if (android.os.Build.VERSION.RELEASE.equals(vers)
7640                        && android.os.Build.VERSION.CODENAME.equals(codename)
7641                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7642                    int num = dis.readInt();
7643                    while (num > 0) {
7644                        num--;
7645                        String pkg = dis.readUTF();
7646                        String cls = dis.readUTF();
7647                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7648                    }
7649                }
7650            }
7651        } catch (FileNotFoundException e) {
7652        } catch (IOException e) {
7653            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7654        } finally {
7655            if (fis != null) {
7656                try {
7657                    fis.close();
7658                } catch (IOException e) {
7659                }
7660            }
7661        }
7662        return lastDoneReceivers;
7663    }
7664
7665    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7666        File file = getCalledPreBootReceiversFile();
7667        FileOutputStream fos = null;
7668        DataOutputStream dos = null;
7669        try {
7670            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7671            fos = new FileOutputStream(file);
7672            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7673            dos.writeInt(LAST_DONE_VERSION);
7674            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7675            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7676            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7677            dos.writeInt(list.size());
7678            for (int i=0; i<list.size(); i++) {
7679                dos.writeUTF(list.get(i).getPackageName());
7680                dos.writeUTF(list.get(i).getClassName());
7681            }
7682        } catch (IOException e) {
7683            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7684            file.delete();
7685        } finally {
7686            FileUtils.sync(fos);
7687            if (dos != null) {
7688                try {
7689                    dos.close();
7690                } catch (IOException e) {
7691                    // TODO Auto-generated catch block
7692                    e.printStackTrace();
7693                }
7694            }
7695        }
7696    }
7697
7698    public void systemReady(final Runnable goingCallback) {
7699        synchronized(this) {
7700            if (mSystemReady) {
7701                if (goingCallback != null) goingCallback.run();
7702                return;
7703            }
7704
7705            // Check to see if there are any update receivers to run.
7706            if (!mDidUpdate) {
7707                if (mWaitingUpdate) {
7708                    return;
7709                }
7710                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7711                List<ResolveInfo> ris = null;
7712                try {
7713                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7714                            intent, null, 0, 0);
7715                } catch (RemoteException e) {
7716                }
7717                if (ris != null) {
7718                    for (int i=ris.size()-1; i>=0; i--) {
7719                        if ((ris.get(i).activityInfo.applicationInfo.flags
7720                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7721                            ris.remove(i);
7722                        }
7723                    }
7724                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7725
7726                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7727
7728                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7729                    for (int i=0; i<ris.size(); i++) {
7730                        ActivityInfo ai = ris.get(i).activityInfo;
7731                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7732                        if (lastDoneReceivers.contains(comp)) {
7733                            ris.remove(i);
7734                            i--;
7735                        }
7736                    }
7737
7738                    final int[] users = getUsersLocked();
7739                    for (int i=0; i<ris.size(); i++) {
7740                        ActivityInfo ai = ris.get(i).activityInfo;
7741                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7742                        doneReceivers.add(comp);
7743                        intent.setComponent(comp);
7744                        for (int j=0; j<users.length; j++) {
7745                            IIntentReceiver finisher = null;
7746                            if (i == ris.size()-1 && j == users.length-1) {
7747                                finisher = new IIntentReceiver.Stub() {
7748                                    public void performReceive(Intent intent, int resultCode,
7749                                            String data, Bundle extras, boolean ordered,
7750                                            boolean sticky, int sendingUser) {
7751                                        // The raw IIntentReceiver interface is called
7752                                        // with the AM lock held, so redispatch to
7753                                        // execute our code without the lock.
7754                                        mHandler.post(new Runnable() {
7755                                            public void run() {
7756                                                synchronized (ActivityManagerService.this) {
7757                                                    mDidUpdate = true;
7758                                                }
7759                                                writeLastDonePreBootReceivers(doneReceivers);
7760                                                showBootMessage(mContext.getText(
7761                                                        R.string.android_upgrading_complete),
7762                                                        false);
7763                                                systemReady(goingCallback);
7764                                            }
7765                                        });
7766                                    }
7767                                };
7768                            }
7769                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7770                                    + " for user " + users[j]);
7771                            broadcastIntentLocked(null, null, intent, null, finisher,
7772                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7773                                    users[j]);
7774                            if (finisher != null) {
7775                                mWaitingUpdate = true;
7776                            }
7777                        }
7778                    }
7779                }
7780                if (mWaitingUpdate) {
7781                    return;
7782                }
7783                mDidUpdate = true;
7784            }
7785
7786            mSystemReady = true;
7787            if (!mStartRunning) {
7788                return;
7789            }
7790        }
7791
7792        ArrayList<ProcessRecord> procsToKill = null;
7793        synchronized(mPidsSelfLocked) {
7794            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7795                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7796                if (!isAllowedWhileBooting(proc.info)){
7797                    if (procsToKill == null) {
7798                        procsToKill = new ArrayList<ProcessRecord>();
7799                    }
7800                    procsToKill.add(proc);
7801                }
7802            }
7803        }
7804
7805        synchronized(this) {
7806            if (procsToKill != null) {
7807                for (int i=procsToKill.size()-1; i>=0; i--) {
7808                    ProcessRecord proc = procsToKill.get(i);
7809                    Slog.i(TAG, "Removing system update proc: " + proc);
7810                    removeProcessLocked(proc, true, false, "system update done");
7811                }
7812            }
7813
7814            // Now that we have cleaned up any update processes, we
7815            // are ready to start launching real processes and know that
7816            // we won't trample on them any more.
7817            mProcessesReady = true;
7818        }
7819
7820        Slog.i(TAG, "System now ready");
7821        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7822            SystemClock.uptimeMillis());
7823
7824        synchronized(this) {
7825            // Make sure we have no pre-ready processes sitting around.
7826
7827            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7828                ResolveInfo ri = mContext.getPackageManager()
7829                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7830                                STOCK_PM_FLAGS);
7831                CharSequence errorMsg = null;
7832                if (ri != null) {
7833                    ActivityInfo ai = ri.activityInfo;
7834                    ApplicationInfo app = ai.applicationInfo;
7835                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7836                        mTopAction = Intent.ACTION_FACTORY_TEST;
7837                        mTopData = null;
7838                        mTopComponent = new ComponentName(app.packageName,
7839                                ai.name);
7840                    } else {
7841                        errorMsg = mContext.getResources().getText(
7842                                com.android.internal.R.string.factorytest_not_system);
7843                    }
7844                } else {
7845                    errorMsg = mContext.getResources().getText(
7846                            com.android.internal.R.string.factorytest_no_action);
7847                }
7848                if (errorMsg != null) {
7849                    mTopAction = null;
7850                    mTopData = null;
7851                    mTopComponent = null;
7852                    Message msg = Message.obtain();
7853                    msg.what = SHOW_FACTORY_ERROR_MSG;
7854                    msg.getData().putCharSequence("msg", errorMsg);
7855                    mHandler.sendMessage(msg);
7856                }
7857            }
7858        }
7859
7860        retrieveSettings();
7861
7862        if (goingCallback != null) goingCallback.run();
7863
7864        synchronized (this) {
7865            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7866                try {
7867                    List apps = AppGlobals.getPackageManager().
7868                        getPersistentApplications(STOCK_PM_FLAGS);
7869                    if (apps != null) {
7870                        int N = apps.size();
7871                        int i;
7872                        for (i=0; i<N; i++) {
7873                            ApplicationInfo info
7874                                = (ApplicationInfo)apps.get(i);
7875                            if (info != null &&
7876                                    !info.packageName.equals("android")) {
7877                                addAppLocked(info, false);
7878                            }
7879                        }
7880                    }
7881                } catch (RemoteException ex) {
7882                    // pm is in same process, this will never happen.
7883                }
7884            }
7885
7886            // Start up initial activity.
7887            mBooting = true;
7888
7889            try {
7890                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7891                    Message msg = Message.obtain();
7892                    msg.what = SHOW_UID_ERROR_MSG;
7893                    mHandler.sendMessage(msg);
7894                }
7895            } catch (RemoteException e) {
7896            }
7897
7898            long ident = Binder.clearCallingIdentity();
7899            try {
7900                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7901                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7902                        | Intent.FLAG_RECEIVER_FOREGROUND);
7903                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7904                broadcastIntentLocked(null, null, intent,
7905                        null, null, 0, null, null, null,
7906                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7907            } finally {
7908                Binder.restoreCallingIdentity(ident);
7909            }
7910            mMainStack.resumeTopActivityLocked(null);
7911            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7912        }
7913    }
7914
7915    private boolean makeAppCrashingLocked(ProcessRecord app,
7916            String shortMsg, String longMsg, String stackTrace) {
7917        app.crashing = true;
7918        app.crashingReport = generateProcessError(app,
7919                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7920        startAppProblemLocked(app);
7921        app.stopFreezingAllLocked();
7922        return handleAppCrashLocked(app);
7923    }
7924
7925    private void makeAppNotRespondingLocked(ProcessRecord app,
7926            String activity, String shortMsg, String longMsg) {
7927        app.notResponding = true;
7928        app.notRespondingReport = generateProcessError(app,
7929                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7930                activity, shortMsg, longMsg, null);
7931        startAppProblemLocked(app);
7932        app.stopFreezingAllLocked();
7933    }
7934
7935    /**
7936     * Generate a process error record, suitable for attachment to a ProcessRecord.
7937     *
7938     * @param app The ProcessRecord in which the error occurred.
7939     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7940     *                      ActivityManager.AppErrorStateInfo
7941     * @param activity The activity associated with the crash, if known.
7942     * @param shortMsg Short message describing the crash.
7943     * @param longMsg Long message describing the crash.
7944     * @param stackTrace Full crash stack trace, may be null.
7945     *
7946     * @return Returns a fully-formed AppErrorStateInfo record.
7947     */
7948    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7949            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7950        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7951
7952        report.condition = condition;
7953        report.processName = app.processName;
7954        report.pid = app.pid;
7955        report.uid = app.info.uid;
7956        report.tag = activity;
7957        report.shortMsg = shortMsg;
7958        report.longMsg = longMsg;
7959        report.stackTrace = stackTrace;
7960
7961        return report;
7962    }
7963
7964    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7965        synchronized (this) {
7966            app.crashing = false;
7967            app.crashingReport = null;
7968            app.notResponding = false;
7969            app.notRespondingReport = null;
7970            if (app.anrDialog == fromDialog) {
7971                app.anrDialog = null;
7972            }
7973            if (app.waitDialog == fromDialog) {
7974                app.waitDialog = null;
7975            }
7976            if (app.pid > 0 && app.pid != MY_PID) {
7977                handleAppCrashLocked(app);
7978                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7979                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
7980                        app.processName, app.setAdj, "user's request after error");
7981                Process.killProcessQuiet(app.pid);
7982            }
7983        }
7984    }
7985
7986    private boolean handleAppCrashLocked(ProcessRecord app) {
7987        if (mHeadless) {
7988            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7989            return false;
7990        }
7991        long now = SystemClock.uptimeMillis();
7992
7993        Long crashTime;
7994        if (!app.isolated) {
7995            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7996        } else {
7997            crashTime = null;
7998        }
7999        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8000            // This process loses!
8001            Slog.w(TAG, "Process " + app.info.processName
8002                    + " has crashed too many times: killing!");
8003            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8004                    app.userId, app.info.processName, app.uid);
8005            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8006                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8007                if (r.app == app) {
8008                    Slog.w(TAG, "  Force finishing activity "
8009                        + r.intent.getComponent().flattenToShortString());
8010                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8011                            null, "crashed", false);
8012                }
8013            }
8014            if (!app.persistent) {
8015                // We don't want to start this process again until the user
8016                // explicitly does so...  but for persistent process, we really
8017                // need to keep it running.  If a persistent process is actually
8018                // repeatedly crashing, then badness for everyone.
8019                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8020                        app.info.processName);
8021                if (!app.isolated) {
8022                    // XXX We don't have a way to mark isolated processes
8023                    // as bad, since they don't have a peristent identity.
8024                    mBadProcesses.put(app.info.processName, app.uid, now);
8025                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8026                }
8027                app.bad = true;
8028                app.removed = true;
8029                // Don't let services in this process be restarted and potentially
8030                // annoy the user repeatedly.  Unless it is persistent, since those
8031                // processes run critical code.
8032                removeProcessLocked(app, false, false, "crash");
8033                mMainStack.resumeTopActivityLocked(null);
8034                return false;
8035            }
8036            mMainStack.resumeTopActivityLocked(null);
8037        } else {
8038            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8039            if (r != null && r.app == app) {
8040                // If the top running activity is from this crashing
8041                // process, then terminate it to avoid getting in a loop.
8042                Slog.w(TAG, "  Force finishing activity "
8043                        + r.intent.getComponent().flattenToShortString());
8044                int index = mMainStack.indexOfActivityLocked(r);
8045                r.stack.finishActivityLocked(r, index,
8046                        Activity.RESULT_CANCELED, null, "crashed", false);
8047                // Also terminate any activities below it that aren't yet
8048                // stopped, to avoid a situation where one will get
8049                // re-start our crashing activity once it gets resumed again.
8050                index--;
8051                if (index >= 0) {
8052                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8053                    if (r.state == ActivityState.RESUMED
8054                            || r.state == ActivityState.PAUSING
8055                            || r.state == ActivityState.PAUSED) {
8056                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8057                            Slog.w(TAG, "  Force finishing activity "
8058                                    + r.intent.getComponent().flattenToShortString());
8059                            r.stack.finishActivityLocked(r, index,
8060                                    Activity.RESULT_CANCELED, null, "crashed", false);
8061                        }
8062                    }
8063                }
8064            }
8065        }
8066
8067        // Bump up the crash count of any services currently running in the proc.
8068        if (app.services.size() != 0) {
8069            // Any services running in the application need to be placed
8070            // back in the pending list.
8071            Iterator<ServiceRecord> it = app.services.iterator();
8072            while (it.hasNext()) {
8073                ServiceRecord sr = it.next();
8074                sr.crashCount++;
8075            }
8076        }
8077
8078        // If the crashing process is what we consider to be the "home process" and it has been
8079        // replaced by a third-party app, clear the package preferred activities from packages
8080        // with a home activity running in the process to prevent a repeatedly crashing app
8081        // from blocking the user to manually clear the list.
8082        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8083                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8084            Iterator it = mHomeProcess.activities.iterator();
8085            while (it.hasNext()) {
8086                ActivityRecord r = (ActivityRecord)it.next();
8087                if (r.isHomeActivity) {
8088                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8089                    try {
8090                        ActivityThread.getPackageManager()
8091                                .clearPackagePreferredActivities(r.packageName);
8092                    } catch (RemoteException c) {
8093                        // pm is in same process, this will never happen.
8094                    }
8095                }
8096            }
8097        }
8098
8099        if (!app.isolated) {
8100            // XXX Can't keep track of crash times for isolated processes,
8101            // because they don't have a perisistent identity.
8102            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8103        }
8104
8105        return true;
8106    }
8107
8108    void startAppProblemLocked(ProcessRecord app) {
8109        if (app.userId == mCurrentUserId) {
8110            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8111                    mContext, app.info.packageName, app.info.flags);
8112        } else {
8113            // If this app is not running under the current user, then we
8114            // can't give it a report button because that would require
8115            // launching the report UI under a different user.
8116            app.errorReportReceiver = null;
8117        }
8118        skipCurrentReceiverLocked(app);
8119    }
8120
8121    void skipCurrentReceiverLocked(ProcessRecord app) {
8122        for (BroadcastQueue queue : mBroadcastQueues) {
8123            queue.skipCurrentReceiverLocked(app);
8124        }
8125    }
8126
8127    /**
8128     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8129     * The application process will exit immediately after this call returns.
8130     * @param app object of the crashing app, null for the system server
8131     * @param crashInfo describing the exception
8132     */
8133    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8134        ProcessRecord r = findAppProcess(app, "Crash");
8135        final String processName = app == null ? "system_server"
8136                : (r == null ? "unknown" : r.processName);
8137
8138        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8139                UserHandle.getUserId(Binder.getCallingUid()), processName,
8140                r == null ? -1 : r.info.flags,
8141                crashInfo.exceptionClassName,
8142                crashInfo.exceptionMessage,
8143                crashInfo.throwFileName,
8144                crashInfo.throwLineNumber);
8145
8146        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8147
8148        crashApplication(r, crashInfo);
8149    }
8150
8151    public void handleApplicationStrictModeViolation(
8152            IBinder app,
8153            int violationMask,
8154            StrictMode.ViolationInfo info) {
8155        ProcessRecord r = findAppProcess(app, "StrictMode");
8156        if (r == null) {
8157            return;
8158        }
8159
8160        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8161            Integer stackFingerprint = info.hashCode();
8162            boolean logIt = true;
8163            synchronized (mAlreadyLoggedViolatedStacks) {
8164                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8165                    logIt = false;
8166                    // TODO: sub-sample into EventLog for these, with
8167                    // the info.durationMillis?  Then we'd get
8168                    // the relative pain numbers, without logging all
8169                    // the stack traces repeatedly.  We'd want to do
8170                    // likewise in the client code, which also does
8171                    // dup suppression, before the Binder call.
8172                } else {
8173                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8174                        mAlreadyLoggedViolatedStacks.clear();
8175                    }
8176                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8177                }
8178            }
8179            if (logIt) {
8180                logStrictModeViolationToDropBox(r, info);
8181            }
8182        }
8183
8184        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8185            AppErrorResult result = new AppErrorResult();
8186            synchronized (this) {
8187                final long origId = Binder.clearCallingIdentity();
8188
8189                Message msg = Message.obtain();
8190                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8191                HashMap<String, Object> data = new HashMap<String, Object>();
8192                data.put("result", result);
8193                data.put("app", r);
8194                data.put("violationMask", violationMask);
8195                data.put("info", info);
8196                msg.obj = data;
8197                mHandler.sendMessage(msg);
8198
8199                Binder.restoreCallingIdentity(origId);
8200            }
8201            int res = result.get();
8202            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8203        }
8204    }
8205
8206    // Depending on the policy in effect, there could be a bunch of
8207    // these in quick succession so we try to batch these together to
8208    // minimize disk writes, number of dropbox entries, and maximize
8209    // compression, by having more fewer, larger records.
8210    private void logStrictModeViolationToDropBox(
8211            ProcessRecord process,
8212            StrictMode.ViolationInfo info) {
8213        if (info == null) {
8214            return;
8215        }
8216        final boolean isSystemApp = process == null ||
8217                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8218                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8219        final String processName = process == null ? "unknown" : process.processName;
8220        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8221        final DropBoxManager dbox = (DropBoxManager)
8222                mContext.getSystemService(Context.DROPBOX_SERVICE);
8223
8224        // Exit early if the dropbox isn't configured to accept this report type.
8225        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8226
8227        boolean bufferWasEmpty;
8228        boolean needsFlush;
8229        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8230        synchronized (sb) {
8231            bufferWasEmpty = sb.length() == 0;
8232            appendDropBoxProcessHeaders(process, processName, sb);
8233            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8234            sb.append("System-App: ").append(isSystemApp).append("\n");
8235            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8236            if (info.violationNumThisLoop != 0) {
8237                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8238            }
8239            if (info.numAnimationsRunning != 0) {
8240                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8241            }
8242            if (info.broadcastIntentAction != null) {
8243                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8244            }
8245            if (info.durationMillis != -1) {
8246                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8247            }
8248            if (info.numInstances != -1) {
8249                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8250            }
8251            if (info.tags != null) {
8252                for (String tag : info.tags) {
8253                    sb.append("Span-Tag: ").append(tag).append("\n");
8254                }
8255            }
8256            sb.append("\n");
8257            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8258                sb.append(info.crashInfo.stackTrace);
8259            }
8260            sb.append("\n");
8261
8262            // Only buffer up to ~64k.  Various logging bits truncate
8263            // things at 128k.
8264            needsFlush = (sb.length() > 64 * 1024);
8265        }
8266
8267        // Flush immediately if the buffer's grown too large, or this
8268        // is a non-system app.  Non-system apps are isolated with a
8269        // different tag & policy and not batched.
8270        //
8271        // Batching is useful during internal testing with
8272        // StrictMode settings turned up high.  Without batching,
8273        // thousands of separate files could be created on boot.
8274        if (!isSystemApp || needsFlush) {
8275            new Thread("Error dump: " + dropboxTag) {
8276                @Override
8277                public void run() {
8278                    String report;
8279                    synchronized (sb) {
8280                        report = sb.toString();
8281                        sb.delete(0, sb.length());
8282                        sb.trimToSize();
8283                    }
8284                    if (report.length() != 0) {
8285                        dbox.addText(dropboxTag, report);
8286                    }
8287                }
8288            }.start();
8289            return;
8290        }
8291
8292        // System app batching:
8293        if (!bufferWasEmpty) {
8294            // An existing dropbox-writing thread is outstanding, so
8295            // we don't need to start it up.  The existing thread will
8296            // catch the buffer appends we just did.
8297            return;
8298        }
8299
8300        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8301        // (After this point, we shouldn't access AMS internal data structures.)
8302        new Thread("Error dump: " + dropboxTag) {
8303            @Override
8304            public void run() {
8305                // 5 second sleep to let stacks arrive and be batched together
8306                try {
8307                    Thread.sleep(5000);  // 5 seconds
8308                } catch (InterruptedException e) {}
8309
8310                String errorReport;
8311                synchronized (mStrictModeBuffer) {
8312                    errorReport = mStrictModeBuffer.toString();
8313                    if (errorReport.length() == 0) {
8314                        return;
8315                    }
8316                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8317                    mStrictModeBuffer.trimToSize();
8318                }
8319                dbox.addText(dropboxTag, errorReport);
8320            }
8321        }.start();
8322    }
8323
8324    /**
8325     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8326     * @param app object of the crashing app, null for the system server
8327     * @param tag reported by the caller
8328     * @param crashInfo describing the context of the error
8329     * @return true if the process should exit immediately (WTF is fatal)
8330     */
8331    public boolean handleApplicationWtf(IBinder app, String tag,
8332            ApplicationErrorReport.CrashInfo crashInfo) {
8333        ProcessRecord r = findAppProcess(app, "WTF");
8334        final String processName = app == null ? "system_server"
8335                : (r == null ? "unknown" : r.processName);
8336
8337        EventLog.writeEvent(EventLogTags.AM_WTF,
8338                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8339                processName,
8340                r == null ? -1 : r.info.flags,
8341                tag, crashInfo.exceptionMessage);
8342
8343        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8344
8345        if (r != null && r.pid != Process.myPid() &&
8346                Settings.Global.getInt(mContext.getContentResolver(),
8347                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8348            crashApplication(r, crashInfo);
8349            return true;
8350        } else {
8351            return false;
8352        }
8353    }
8354
8355    /**
8356     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8357     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8358     */
8359    private ProcessRecord findAppProcess(IBinder app, String reason) {
8360        if (app == null) {
8361            return null;
8362        }
8363
8364        synchronized (this) {
8365            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8366                final int NA = apps.size();
8367                for (int ia=0; ia<NA; ia++) {
8368                    ProcessRecord p = apps.valueAt(ia);
8369                    if (p.thread != null && p.thread.asBinder() == app) {
8370                        return p;
8371                    }
8372                }
8373            }
8374
8375            Slog.w(TAG, "Can't find mystery application for " + reason
8376                    + " from pid=" + Binder.getCallingPid()
8377                    + " uid=" + Binder.getCallingUid() + ": " + app);
8378            return null;
8379        }
8380    }
8381
8382    /**
8383     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8384     * to append various headers to the dropbox log text.
8385     */
8386    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8387            StringBuilder sb) {
8388        // Watchdog thread ends up invoking this function (with
8389        // a null ProcessRecord) to add the stack file to dropbox.
8390        // Do not acquire a lock on this (am) in such cases, as it
8391        // could cause a potential deadlock, if and when watchdog
8392        // is invoked due to unavailability of lock on am and it
8393        // would prevent watchdog from killing system_server.
8394        if (process == null) {
8395            sb.append("Process: ").append(processName).append("\n");
8396            return;
8397        }
8398        // Note: ProcessRecord 'process' is guarded by the service
8399        // instance.  (notably process.pkgList, which could otherwise change
8400        // concurrently during execution of this method)
8401        synchronized (this) {
8402            sb.append("Process: ").append(processName).append("\n");
8403            int flags = process.info.flags;
8404            IPackageManager pm = AppGlobals.getPackageManager();
8405            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8406            for (String pkg : process.pkgList) {
8407                sb.append("Package: ").append(pkg);
8408                try {
8409                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8410                    if (pi != null) {
8411                        sb.append(" v").append(pi.versionCode);
8412                        if (pi.versionName != null) {
8413                            sb.append(" (").append(pi.versionName).append(")");
8414                        }
8415                    }
8416                } catch (RemoteException e) {
8417                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8418                }
8419                sb.append("\n");
8420            }
8421        }
8422    }
8423
8424    private static String processClass(ProcessRecord process) {
8425        if (process == null || process.pid == MY_PID) {
8426            return "system_server";
8427        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8428            return "system_app";
8429        } else {
8430            return "data_app";
8431        }
8432    }
8433
8434    /**
8435     * Write a description of an error (crash, WTF, ANR) to the drop box.
8436     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8437     * @param process which caused the error, null means the system server
8438     * @param activity which triggered the error, null if unknown
8439     * @param parent activity related to the error, null if unknown
8440     * @param subject line related to the error, null if absent
8441     * @param report in long form describing the error, null if absent
8442     * @param logFile to include in the report, null if none
8443     * @param crashInfo giving an application stack trace, null if absent
8444     */
8445    public void addErrorToDropBox(String eventType,
8446            ProcessRecord process, String processName, ActivityRecord activity,
8447            ActivityRecord parent, String subject,
8448            final String report, final File logFile,
8449            final ApplicationErrorReport.CrashInfo crashInfo) {
8450        // NOTE -- this must never acquire the ActivityManagerService lock,
8451        // otherwise the watchdog may be prevented from resetting the system.
8452
8453        final String dropboxTag = processClass(process) + "_" + eventType;
8454        final DropBoxManager dbox = (DropBoxManager)
8455                mContext.getSystemService(Context.DROPBOX_SERVICE);
8456
8457        // Exit early if the dropbox isn't configured to accept this report type.
8458        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8459
8460        final StringBuilder sb = new StringBuilder(1024);
8461        appendDropBoxProcessHeaders(process, processName, sb);
8462        if (activity != null) {
8463            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8464        }
8465        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8466            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8467        }
8468        if (parent != null && parent != activity) {
8469            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8470        }
8471        if (subject != null) {
8472            sb.append("Subject: ").append(subject).append("\n");
8473        }
8474        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8475        if (Debug.isDebuggerConnected()) {
8476            sb.append("Debugger: Connected\n");
8477        }
8478        sb.append("\n");
8479
8480        // Do the rest in a worker thread to avoid blocking the caller on I/O
8481        // (After this point, we shouldn't access AMS internal data structures.)
8482        Thread worker = new Thread("Error dump: " + dropboxTag) {
8483            @Override
8484            public void run() {
8485                if (report != null) {
8486                    sb.append(report);
8487                }
8488                if (logFile != null) {
8489                    try {
8490                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8491                    } catch (IOException e) {
8492                        Slog.e(TAG, "Error reading " + logFile, e);
8493                    }
8494                }
8495                if (crashInfo != null && crashInfo.stackTrace != null) {
8496                    sb.append(crashInfo.stackTrace);
8497                }
8498
8499                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8500                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8501                if (lines > 0) {
8502                    sb.append("\n");
8503
8504                    // Merge several logcat streams, and take the last N lines
8505                    InputStreamReader input = null;
8506                    try {
8507                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8508                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8509                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8510
8511                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8512                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8513                        input = new InputStreamReader(logcat.getInputStream());
8514
8515                        int num;
8516                        char[] buf = new char[8192];
8517                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8518                    } catch (IOException e) {
8519                        Slog.e(TAG, "Error running logcat", e);
8520                    } finally {
8521                        if (input != null) try { input.close(); } catch (IOException e) {}
8522                    }
8523                }
8524
8525                dbox.addText(dropboxTag, sb.toString());
8526            }
8527        };
8528
8529        if (process == null) {
8530            // If process is null, we are being called from some internal code
8531            // and may be about to die -- run this synchronously.
8532            worker.run();
8533        } else {
8534            worker.start();
8535        }
8536    }
8537
8538    /**
8539     * Bring up the "unexpected error" dialog box for a crashing app.
8540     * Deal with edge cases (intercepts from instrumented applications,
8541     * ActivityController, error intent receivers, that sort of thing).
8542     * @param r the application crashing
8543     * @param crashInfo describing the failure
8544     */
8545    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8546        long timeMillis = System.currentTimeMillis();
8547        String shortMsg = crashInfo.exceptionClassName;
8548        String longMsg = crashInfo.exceptionMessage;
8549        String stackTrace = crashInfo.stackTrace;
8550        if (shortMsg != null && longMsg != null) {
8551            longMsg = shortMsg + ": " + longMsg;
8552        } else if (shortMsg != null) {
8553            longMsg = shortMsg;
8554        }
8555
8556        AppErrorResult result = new AppErrorResult();
8557        synchronized (this) {
8558            if (mController != null) {
8559                try {
8560                    String name = r != null ? r.processName : null;
8561                    int pid = r != null ? r.pid : Binder.getCallingPid();
8562                    if (!mController.appCrashed(name, pid,
8563                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8564                        Slog.w(TAG, "Force-killing crashed app " + name
8565                                + " at watcher's request");
8566                        Process.killProcess(pid);
8567                        return;
8568                    }
8569                } catch (RemoteException e) {
8570                    mController = null;
8571                }
8572            }
8573
8574            final long origId = Binder.clearCallingIdentity();
8575
8576            // If this process is running instrumentation, finish it.
8577            if (r != null && r.instrumentationClass != null) {
8578                Slog.w(TAG, "Error in app " + r.processName
8579                      + " running instrumentation " + r.instrumentationClass + ":");
8580                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8581                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8582                Bundle info = new Bundle();
8583                info.putString("shortMsg", shortMsg);
8584                info.putString("longMsg", longMsg);
8585                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8586                Binder.restoreCallingIdentity(origId);
8587                return;
8588            }
8589
8590            // If we can't identify the process or it's already exceeded its crash quota,
8591            // quit right away without showing a crash dialog.
8592            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8593                Binder.restoreCallingIdentity(origId);
8594                return;
8595            }
8596
8597            Message msg = Message.obtain();
8598            msg.what = SHOW_ERROR_MSG;
8599            HashMap data = new HashMap();
8600            data.put("result", result);
8601            data.put("app", r);
8602            msg.obj = data;
8603            mHandler.sendMessage(msg);
8604
8605            Binder.restoreCallingIdentity(origId);
8606        }
8607
8608        int res = result.get();
8609
8610        Intent appErrorIntent = null;
8611        synchronized (this) {
8612            if (r != null && !r.isolated) {
8613                // XXX Can't keep track of crash time for isolated processes,
8614                // since they don't have a persistent identity.
8615                mProcessCrashTimes.put(r.info.processName, r.uid,
8616                        SystemClock.uptimeMillis());
8617            }
8618            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8619                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8620            }
8621        }
8622
8623        if (appErrorIntent != null) {
8624            try {
8625                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8626            } catch (ActivityNotFoundException e) {
8627                Slog.w(TAG, "bug report receiver dissappeared", e);
8628            }
8629        }
8630    }
8631
8632    Intent createAppErrorIntentLocked(ProcessRecord r,
8633            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8634        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8635        if (report == null) {
8636            return null;
8637        }
8638        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8639        result.setComponent(r.errorReportReceiver);
8640        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8641        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8642        return result;
8643    }
8644
8645    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8646            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8647        if (r.errorReportReceiver == null) {
8648            return null;
8649        }
8650
8651        if (!r.crashing && !r.notResponding) {
8652            return null;
8653        }
8654
8655        ApplicationErrorReport report = new ApplicationErrorReport();
8656        report.packageName = r.info.packageName;
8657        report.installerPackageName = r.errorReportReceiver.getPackageName();
8658        report.processName = r.processName;
8659        report.time = timeMillis;
8660        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8661
8662        if (r.crashing) {
8663            report.type = ApplicationErrorReport.TYPE_CRASH;
8664            report.crashInfo = crashInfo;
8665        } else if (r.notResponding) {
8666            report.type = ApplicationErrorReport.TYPE_ANR;
8667            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8668
8669            report.anrInfo.activity = r.notRespondingReport.tag;
8670            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8671            report.anrInfo.info = r.notRespondingReport.longMsg;
8672        }
8673
8674        return report;
8675    }
8676
8677    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8678        enforceNotIsolatedCaller("getProcessesInErrorState");
8679        // assume our apps are happy - lazy create the list
8680        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8681
8682        final boolean allUsers = ActivityManager.checkUidPermission(
8683                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8684                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8685        int userId = UserHandle.getUserId(Binder.getCallingUid());
8686
8687        synchronized (this) {
8688
8689            // iterate across all processes
8690            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8691                ProcessRecord app = mLruProcesses.get(i);
8692                if (!allUsers && app.userId != userId) {
8693                    continue;
8694                }
8695                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8696                    // This one's in trouble, so we'll generate a report for it
8697                    // crashes are higher priority (in case there's a crash *and* an anr)
8698                    ActivityManager.ProcessErrorStateInfo report = null;
8699                    if (app.crashing) {
8700                        report = app.crashingReport;
8701                    } else if (app.notResponding) {
8702                        report = app.notRespondingReport;
8703                    }
8704
8705                    if (report != null) {
8706                        if (errList == null) {
8707                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8708                        }
8709                        errList.add(report);
8710                    } else {
8711                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8712                                " crashing = " + app.crashing +
8713                                " notResponding = " + app.notResponding);
8714                    }
8715                }
8716            }
8717        }
8718
8719        return errList;
8720    }
8721
8722    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8723        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8724            if (currApp != null) {
8725                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8726            }
8727            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8728        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8729            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8730        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8731            if (currApp != null) {
8732                currApp.lru = 0;
8733            }
8734            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8735        } else if (adj >= ProcessList.SERVICE_ADJ) {
8736            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8737        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8738            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8739        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8740            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8741        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8742            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8743        } else {
8744            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8745        }
8746    }
8747
8748    private void fillInProcMemInfo(ProcessRecord app,
8749            ActivityManager.RunningAppProcessInfo outInfo) {
8750        outInfo.pid = app.pid;
8751        outInfo.uid = app.info.uid;
8752        if (mHeavyWeightProcess == app) {
8753            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8754        }
8755        if (app.persistent) {
8756            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8757        }
8758        if (app.hasActivities) {
8759            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8760        }
8761        outInfo.lastTrimLevel = app.trimMemoryLevel;
8762        int adj = app.curAdj;
8763        outInfo.importance = oomAdjToImportance(adj, outInfo);
8764        outInfo.importanceReasonCode = app.adjTypeCode;
8765    }
8766
8767    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8768        enforceNotIsolatedCaller("getRunningAppProcesses");
8769        // Lazy instantiation of list
8770        List<ActivityManager.RunningAppProcessInfo> runList = null;
8771        final boolean allUsers = ActivityManager.checkUidPermission(
8772                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8773                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8774        int userId = UserHandle.getUserId(Binder.getCallingUid());
8775        synchronized (this) {
8776            // Iterate across all processes
8777            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8778                ProcessRecord app = mLruProcesses.get(i);
8779                if (!allUsers && app.userId != userId) {
8780                    continue;
8781                }
8782                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8783                    // Generate process state info for running application
8784                    ActivityManager.RunningAppProcessInfo currApp =
8785                        new ActivityManager.RunningAppProcessInfo(app.processName,
8786                                app.pid, app.getPackageList());
8787                    fillInProcMemInfo(app, currApp);
8788                    if (app.adjSource instanceof ProcessRecord) {
8789                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8790                        currApp.importanceReasonImportance = oomAdjToImportance(
8791                                app.adjSourceOom, null);
8792                    } else if (app.adjSource instanceof ActivityRecord) {
8793                        ActivityRecord r = (ActivityRecord)app.adjSource;
8794                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8795                    }
8796                    if (app.adjTarget instanceof ComponentName) {
8797                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8798                    }
8799                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8800                    //        + " lru=" + currApp.lru);
8801                    if (runList == null) {
8802                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8803                    }
8804                    runList.add(currApp);
8805                }
8806            }
8807        }
8808        return runList;
8809    }
8810
8811    public List<ApplicationInfo> getRunningExternalApplications() {
8812        enforceNotIsolatedCaller("getRunningExternalApplications");
8813        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8814        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8815        if (runningApps != null && runningApps.size() > 0) {
8816            Set<String> extList = new HashSet<String>();
8817            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8818                if (app.pkgList != null) {
8819                    for (String pkg : app.pkgList) {
8820                        extList.add(pkg);
8821                    }
8822                }
8823            }
8824            IPackageManager pm = AppGlobals.getPackageManager();
8825            for (String pkg : extList) {
8826                try {
8827                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8828                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8829                        retList.add(info);
8830                    }
8831                } catch (RemoteException e) {
8832                }
8833            }
8834        }
8835        return retList;
8836    }
8837
8838    @Override
8839    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8840        enforceNotIsolatedCaller("getMyMemoryState");
8841        synchronized (this) {
8842            ProcessRecord proc;
8843            synchronized (mPidsSelfLocked) {
8844                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8845            }
8846            fillInProcMemInfo(proc, outInfo);
8847        }
8848    }
8849
8850    @Override
8851    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8852        if (checkCallingPermission(android.Manifest.permission.DUMP)
8853                != PackageManager.PERMISSION_GRANTED) {
8854            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8855                    + Binder.getCallingPid()
8856                    + ", uid=" + Binder.getCallingUid()
8857                    + " without permission "
8858                    + android.Manifest.permission.DUMP);
8859            return;
8860        }
8861
8862        boolean dumpAll = false;
8863        boolean dumpClient = false;
8864        String dumpPackage = null;
8865
8866        int opti = 0;
8867        while (opti < args.length) {
8868            String opt = args[opti];
8869            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8870                break;
8871            }
8872            opti++;
8873            if ("-a".equals(opt)) {
8874                dumpAll = true;
8875            } else if ("-c".equals(opt)) {
8876                dumpClient = true;
8877            } else if ("-h".equals(opt)) {
8878                pw.println("Activity manager dump options:");
8879                pw.println("  [-a] [-c] [-h] [cmd] ...");
8880                pw.println("  cmd may be one of:");
8881                pw.println("    a[ctivities]: activity stack state");
8882                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8883                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8884                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8885                pw.println("    o[om]: out of memory management");
8886                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8887                pw.println("    provider [COMP_SPEC]: provider client-side state");
8888                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8889                pw.println("    service [COMP_SPEC]: service client-side state");
8890                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8891                pw.println("    all: dump all activities");
8892                pw.println("    top: dump the top activity");
8893                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8894                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8895                pw.println("    a partial substring in a component name, a");
8896                pw.println("    hex object identifier.");
8897                pw.println("  -a: include all available server state.");
8898                pw.println("  -c: include client state.");
8899                return;
8900            } else {
8901                pw.println("Unknown argument: " + opt + "; use -h for help");
8902            }
8903        }
8904
8905        long origId = Binder.clearCallingIdentity();
8906        boolean more = false;
8907        // Is the caller requesting to dump a particular piece of data?
8908        if (opti < args.length) {
8909            String cmd = args[opti];
8910            opti++;
8911            if ("activities".equals(cmd) || "a".equals(cmd)) {
8912                synchronized (this) {
8913                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8914                }
8915            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8916                String[] newArgs;
8917                String name;
8918                if (opti >= args.length) {
8919                    name = null;
8920                    newArgs = EMPTY_STRING_ARRAY;
8921                } else {
8922                    name = args[opti];
8923                    opti++;
8924                    newArgs = new String[args.length - opti];
8925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8926                            args.length - opti);
8927                }
8928                synchronized (this) {
8929                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8930                }
8931            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8932                String[] newArgs;
8933                String name;
8934                if (opti >= args.length) {
8935                    name = null;
8936                    newArgs = EMPTY_STRING_ARRAY;
8937                } else {
8938                    name = args[opti];
8939                    opti++;
8940                    newArgs = new String[args.length - opti];
8941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8942                            args.length - opti);
8943                }
8944                synchronized (this) {
8945                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8946                }
8947            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8948                String[] newArgs;
8949                String name;
8950                if (opti >= args.length) {
8951                    name = null;
8952                    newArgs = EMPTY_STRING_ARRAY;
8953                } else {
8954                    name = args[opti];
8955                    opti++;
8956                    newArgs = new String[args.length - opti];
8957                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8958                            args.length - opti);
8959                }
8960                synchronized (this) {
8961                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8962                }
8963            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8964                synchronized (this) {
8965                    dumpOomLocked(fd, pw, args, opti, true);
8966                }
8967            } else if ("provider".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, args.length - opti);
8978                }
8979                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8980                    pw.println("No providers match: " + name);
8981                    pw.println("Use -h for help.");
8982                }
8983            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8984                synchronized (this) {
8985                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8986                }
8987            } else if ("service".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,
8998                            args.length - opti);
8999                }
9000                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9001                    pw.println("No services match: " + name);
9002                    pw.println("Use -h for help.");
9003                }
9004            } else if ("package".equals(cmd)) {
9005                String[] newArgs;
9006                if (opti >= args.length) {
9007                    pw.println("package: no package name specified");
9008                    pw.println("Use -h for help.");
9009                } else {
9010                    dumpPackage = args[opti];
9011                    opti++;
9012                    newArgs = new String[args.length - opti];
9013                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9014                            args.length - opti);
9015                    args = newArgs;
9016                    opti = 0;
9017                    more = true;
9018                }
9019            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9020                synchronized (this) {
9021                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9022                }
9023            } else {
9024                // Dumping a single activity?
9025                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9026                    pw.println("Bad activity command, or no activities match: " + cmd);
9027                    pw.println("Use -h for help.");
9028                }
9029            }
9030            if (!more) {
9031                Binder.restoreCallingIdentity(origId);
9032                return;
9033            }
9034        }
9035
9036        // No piece of data specified, dump everything.
9037        synchronized (this) {
9038            boolean needSep;
9039            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9040            if (needSep) {
9041                pw.println(" ");
9042            }
9043            if (dumpAll) {
9044                pw.println("-------------------------------------------------------------------------------");
9045            }
9046            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9047            if (needSep) {
9048                pw.println(" ");
9049            }
9050            if (dumpAll) {
9051                pw.println("-------------------------------------------------------------------------------");
9052            }
9053            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9054            if (needSep) {
9055                pw.println(" ");
9056            }
9057            if (dumpAll) {
9058                pw.println("-------------------------------------------------------------------------------");
9059            }
9060            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9061            if (needSep) {
9062                pw.println(" ");
9063            }
9064            if (dumpAll) {
9065                pw.println("-------------------------------------------------------------------------------");
9066            }
9067            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9068            if (needSep) {
9069                pw.println(" ");
9070            }
9071            if (dumpAll) {
9072                pw.println("-------------------------------------------------------------------------------");
9073            }
9074            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9075        }
9076        Binder.restoreCallingIdentity(origId);
9077    }
9078
9079    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9080            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9081        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9082        pw.println("  Main stack:");
9083        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9084                dumpPackage);
9085        pw.println(" ");
9086        pw.println("  Running activities (most recent first):");
9087        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9088                dumpPackage);
9089        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9090            pw.println(" ");
9091            pw.println("  Activities waiting for another to become visible:");
9092            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9093                    !dumpAll, false, dumpPackage);
9094        }
9095        if (mMainStack.mStoppingActivities.size() > 0) {
9096            pw.println(" ");
9097            pw.println("  Activities waiting to stop:");
9098            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9099                    !dumpAll, false, dumpPackage);
9100        }
9101        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9102            pw.println(" ");
9103            pw.println("  Activities waiting to sleep:");
9104            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9105                    !dumpAll, false, dumpPackage);
9106        }
9107        if (mMainStack.mFinishingActivities.size() > 0) {
9108            pw.println(" ");
9109            pw.println("  Activities waiting to finish:");
9110            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9111                    !dumpAll, false, dumpPackage);
9112        }
9113
9114        pw.println(" ");
9115        if (mMainStack.mPausingActivity != null) {
9116            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9117        }
9118        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9119        pw.println("  mFocusedActivity: " + mFocusedActivity);
9120        if (dumpAll) {
9121            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9122            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9123            pw.println("  mDismissKeyguardOnNextActivity: "
9124                    + mMainStack.mDismissKeyguardOnNextActivity);
9125        }
9126
9127        if (mRecentTasks.size() > 0) {
9128            pw.println();
9129            pw.println("  Recent tasks:");
9130
9131            final int N = mRecentTasks.size();
9132            for (int i=0; i<N; i++) {
9133                TaskRecord tr = mRecentTasks.get(i);
9134                if (dumpPackage != null) {
9135                    if (tr.realActivity == null ||
9136                            !dumpPackage.equals(tr.realActivity)) {
9137                        continue;
9138                    }
9139                }
9140                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9141                        pw.println(tr);
9142                if (dumpAll) {
9143                    mRecentTasks.get(i).dump(pw, "    ");
9144                }
9145            }
9146        }
9147
9148        if (dumpAll) {
9149            pw.println(" ");
9150            pw.println("  mCurTask: " + mCurTask);
9151        }
9152
9153        return true;
9154    }
9155
9156    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9157            int opti, boolean dumpAll, String dumpPackage) {
9158        boolean needSep = false;
9159        int numPers = 0;
9160
9161        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9162
9163        if (dumpAll) {
9164            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9165                final int NA = procs.size();
9166                for (int ia=0; ia<NA; ia++) {
9167                    ProcessRecord r = procs.valueAt(ia);
9168                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9169                        continue;
9170                    }
9171                    if (!needSep) {
9172                        pw.println("  All known processes:");
9173                        needSep = true;
9174                    }
9175                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9176                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9177                        pw.print(" "); pw.println(r);
9178                    r.dump(pw, "    ");
9179                    if (r.persistent) {
9180                        numPers++;
9181                    }
9182                }
9183            }
9184        }
9185
9186        if (mIsolatedProcesses.size() > 0) {
9187            if (needSep) pw.println(" ");
9188            needSep = true;
9189            pw.println("  Isolated process list (sorted by uid):");
9190            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9191                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9192                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9193                    continue;
9194                }
9195                pw.println(String.format("%sIsolated #%2d: %s",
9196                        "    ", i, r.toString()));
9197            }
9198        }
9199
9200        if (mLruProcesses.size() > 0) {
9201            if (needSep) pw.println(" ");
9202            needSep = true;
9203            pw.println("  Process LRU list (sorted by oom_adj):");
9204            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9205                    "Proc", "PERS", false, dumpPackage);
9206            needSep = true;
9207        }
9208
9209        if (dumpAll) {
9210            synchronized (mPidsSelfLocked) {
9211                boolean printed = false;
9212                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9213                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9214                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9215                        continue;
9216                    }
9217                    if (!printed) {
9218                        if (needSep) pw.println(" ");
9219                        needSep = true;
9220                        pw.println("  PID mappings:");
9221                        printed = true;
9222                    }
9223                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9224                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9225                }
9226            }
9227        }
9228
9229        if (mForegroundProcesses.size() > 0) {
9230            synchronized (mPidsSelfLocked) {
9231                boolean printed = false;
9232                for (int i=0; i<mForegroundProcesses.size(); i++) {
9233                    ProcessRecord r = mPidsSelfLocked.get(
9234                            mForegroundProcesses.valueAt(i).pid);
9235                    if (dumpPackage != null && (r == null
9236                            || !dumpPackage.equals(r.info.packageName))) {
9237                        continue;
9238                    }
9239                    if (!printed) {
9240                        if (needSep) pw.println(" ");
9241                        needSep = true;
9242                        pw.println("  Foreground Processes:");
9243                        printed = true;
9244                    }
9245                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9246                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9247                }
9248            }
9249        }
9250
9251        if (mPersistentStartingProcesses.size() > 0) {
9252            if (needSep) pw.println(" ");
9253            needSep = true;
9254            pw.println("  Persisent processes that are starting:");
9255            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9256                    "Starting Norm", "Restarting PERS", dumpPackage);
9257        }
9258
9259        if (mRemovedProcesses.size() > 0) {
9260            if (needSep) pw.println(" ");
9261            needSep = true;
9262            pw.println("  Processes that are being removed:");
9263            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9264                    "Removed Norm", "Removed PERS", dumpPackage);
9265        }
9266
9267        if (mProcessesOnHold.size() > 0) {
9268            if (needSep) pw.println(" ");
9269            needSep = true;
9270            pw.println("  Processes that are on old until the system is ready:");
9271            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9272                    "OnHold Norm", "OnHold PERS", dumpPackage);
9273        }
9274
9275        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9276
9277        if (mProcessCrashTimes.getMap().size() > 0) {
9278            boolean printed = false;
9279            long now = SystemClock.uptimeMillis();
9280            for (Map.Entry<String, SparseArray<Long>> procs
9281                    : mProcessCrashTimes.getMap().entrySet()) {
9282                String pname = procs.getKey();
9283                SparseArray<Long> uids = procs.getValue();
9284                final int N = uids.size();
9285                for (int i=0; i<N; i++) {
9286                    int puid = uids.keyAt(i);
9287                    ProcessRecord r = mProcessNames.get(pname, puid);
9288                    if (dumpPackage != null && (r == null
9289                            || !dumpPackage.equals(r.info.packageName))) {
9290                        continue;
9291                    }
9292                    if (!printed) {
9293                        if (needSep) pw.println(" ");
9294                        needSep = true;
9295                        pw.println("  Time since processes crashed:");
9296                        printed = true;
9297                    }
9298                    pw.print("    Process "); pw.print(pname);
9299                            pw.print(" uid "); pw.print(puid);
9300                            pw.print(": last crashed ");
9301                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9302                            pw.println(" ago");
9303                }
9304            }
9305        }
9306
9307        if (mBadProcesses.getMap().size() > 0) {
9308            boolean printed = false;
9309            for (Map.Entry<String, SparseArray<Long>> procs
9310                    : mBadProcesses.getMap().entrySet()) {
9311                String pname = procs.getKey();
9312                SparseArray<Long> uids = procs.getValue();
9313                final int N = uids.size();
9314                for (int i=0; i<N; i++) {
9315                    int puid = uids.keyAt(i);
9316                    ProcessRecord r = mProcessNames.get(pname, puid);
9317                    if (dumpPackage != null && (r == null
9318                            || !dumpPackage.equals(r.info.packageName))) {
9319                        continue;
9320                    }
9321                    if (!printed) {
9322                        if (needSep) pw.println(" ");
9323                        needSep = true;
9324                        pw.println("  Bad processes:");
9325                    }
9326                    pw.print("    Bad process "); pw.print(pname);
9327                            pw.print(" uid "); pw.print(puid);
9328                            pw.print(": crashed at time ");
9329                            pw.println(uids.valueAt(i));
9330                }
9331            }
9332        }
9333
9334        pw.println();
9335        pw.println("  mStartedUsers:");
9336        for (int i=0; i<mStartedUsers.size(); i++) {
9337            UserStartedState uss = mStartedUsers.valueAt(i);
9338            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9339                    pw.print(": "); uss.dump("", pw);
9340        }
9341        pw.print("  mStartedUserArray: [");
9342        for (int i=0; i<mStartedUserArray.length; i++) {
9343            if (i > 0) pw.print(", ");
9344            pw.print(mStartedUserArray[i]);
9345        }
9346        pw.println("]");
9347        pw.print("  mUserLru: [");
9348        for (int i=0; i<mUserLru.size(); i++) {
9349            if (i > 0) pw.print(", ");
9350            pw.print(mUserLru.get(i));
9351        }
9352        pw.println("]");
9353        if (dumpAll) {
9354            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9355        }
9356        pw.println("  mHomeProcess: " + mHomeProcess);
9357        pw.println("  mPreviousProcess: " + mPreviousProcess);
9358        if (dumpAll) {
9359            StringBuilder sb = new StringBuilder(128);
9360            sb.append("  mPreviousProcessVisibleTime: ");
9361            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9362            pw.println(sb);
9363        }
9364        if (mHeavyWeightProcess != null) {
9365            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9366        }
9367        pw.println("  mConfiguration: " + mConfiguration);
9368        if (dumpAll) {
9369            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9370            if (mCompatModePackages.getPackages().size() > 0) {
9371                boolean printed = false;
9372                for (Map.Entry<String, Integer> entry
9373                        : mCompatModePackages.getPackages().entrySet()) {
9374                    String pkg = entry.getKey();
9375                    int mode = entry.getValue();
9376                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9377                        continue;
9378                    }
9379                    if (!printed) {
9380                        pw.println("  mScreenCompatPackages:");
9381                        printed = true;
9382                    }
9383                    pw.print("    "); pw.print(pkg); pw.print(": ");
9384                            pw.print(mode); pw.println();
9385                }
9386            }
9387        }
9388        if (mSleeping || mWentToSleep || mLockScreenShown) {
9389            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9390                    + " mLockScreenShown " + mLockScreenShown);
9391        }
9392        if (mShuttingDown) {
9393            pw.println("  mShuttingDown=" + mShuttingDown);
9394        }
9395        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9396                || mOrigWaitForDebugger) {
9397            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9398                    + " mDebugTransient=" + mDebugTransient
9399                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9400        }
9401        if (mOpenGlTraceApp != null) {
9402            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9403        }
9404        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9405                || mProfileFd != null) {
9406            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9407            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9408            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9409                    + mAutoStopProfiler);
9410        }
9411        if (mAlwaysFinishActivities || mController != null) {
9412            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9413                    + " mController=" + mController);
9414        }
9415        if (dumpAll) {
9416            pw.println("  Total persistent processes: " + numPers);
9417            pw.println("  mStartRunning=" + mStartRunning
9418                    + " mProcessesReady=" + mProcessesReady
9419                    + " mSystemReady=" + mSystemReady);
9420            pw.println("  mBooting=" + mBooting
9421                    + " mBooted=" + mBooted
9422                    + " mFactoryTest=" + mFactoryTest);
9423            pw.print("  mLastPowerCheckRealtime=");
9424                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9425                    pw.println("");
9426            pw.print("  mLastPowerCheckUptime=");
9427                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9428                    pw.println("");
9429            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9430            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9431            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9432            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9433                    + " mNumHiddenProcs=" + mNumHiddenProcs
9434                    + " mNumServiceProcs=" + mNumServiceProcs
9435                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9436        }
9437
9438        return true;
9439    }
9440
9441    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9442            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9443        if (mProcessesToGc.size() > 0) {
9444            boolean printed = false;
9445            long now = SystemClock.uptimeMillis();
9446            for (int i=0; i<mProcessesToGc.size(); i++) {
9447                ProcessRecord proc = mProcessesToGc.get(i);
9448                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9449                    continue;
9450                }
9451                if (!printed) {
9452                    if (needSep) pw.println(" ");
9453                    needSep = true;
9454                    pw.println("  Processes that are waiting to GC:");
9455                    printed = true;
9456                }
9457                pw.print("    Process "); pw.println(proc);
9458                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9459                        pw.print(", last gced=");
9460                        pw.print(now-proc.lastRequestedGc);
9461                        pw.print(" ms ago, last lowMem=");
9462                        pw.print(now-proc.lastLowMemory);
9463                        pw.println(" ms ago");
9464
9465            }
9466        }
9467        return needSep;
9468    }
9469
9470    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9471            int opti, boolean dumpAll) {
9472        boolean needSep = false;
9473
9474        if (mLruProcesses.size() > 0) {
9475            if (needSep) pw.println(" ");
9476            needSep = true;
9477            pw.println("  OOM levels:");
9478            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9479            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9480            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9481            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9482            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9483            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9484            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9485            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9486            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9487            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9488            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9489            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9490            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9491
9492            if (needSep) pw.println(" ");
9493            needSep = true;
9494            pw.println("  Process OOM control:");
9495            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9496                    "Proc", "PERS", true, null);
9497            needSep = true;
9498        }
9499
9500        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9501
9502        pw.println();
9503        pw.println("  mHomeProcess: " + mHomeProcess);
9504        pw.println("  mPreviousProcess: " + mPreviousProcess);
9505        if (mHeavyWeightProcess != null) {
9506            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9507        }
9508
9509        return true;
9510    }
9511
9512    /**
9513     * There are three ways to call this:
9514     *  - no provider specified: dump all the providers
9515     *  - a flattened component name that matched an existing provider was specified as the
9516     *    first arg: dump that one provider
9517     *  - the first arg isn't the flattened component name of an existing provider:
9518     *    dump all providers whose component contains the first arg as a substring
9519     */
9520    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9521            int opti, boolean dumpAll) {
9522        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9523    }
9524
9525    static class ItemMatcher {
9526        ArrayList<ComponentName> components;
9527        ArrayList<String> strings;
9528        ArrayList<Integer> objects;
9529        boolean all;
9530
9531        ItemMatcher() {
9532            all = true;
9533        }
9534
9535        void build(String name) {
9536            ComponentName componentName = ComponentName.unflattenFromString(name);
9537            if (componentName != null) {
9538                if (components == null) {
9539                    components = new ArrayList<ComponentName>();
9540                }
9541                components.add(componentName);
9542                all = false;
9543            } else {
9544                int objectId = 0;
9545                // Not a '/' separated full component name; maybe an object ID?
9546                try {
9547                    objectId = Integer.parseInt(name, 16);
9548                    if (objects == null) {
9549                        objects = new ArrayList<Integer>();
9550                    }
9551                    objects.add(objectId);
9552                    all = false;
9553                } catch (RuntimeException e) {
9554                    // Not an integer; just do string match.
9555                    if (strings == null) {
9556                        strings = new ArrayList<String>();
9557                    }
9558                    strings.add(name);
9559                    all = false;
9560                }
9561            }
9562        }
9563
9564        int build(String[] args, int opti) {
9565            for (; opti<args.length; opti++) {
9566                String name = args[opti];
9567                if ("--".equals(name)) {
9568                    return opti+1;
9569                }
9570                build(name);
9571            }
9572            return opti;
9573        }
9574
9575        boolean match(Object object, ComponentName comp) {
9576            if (all) {
9577                return true;
9578            }
9579            if (components != null) {
9580                for (int i=0; i<components.size(); i++) {
9581                    if (components.get(i).equals(comp)) {
9582                        return true;
9583                    }
9584                }
9585            }
9586            if (objects != null) {
9587                for (int i=0; i<objects.size(); i++) {
9588                    if (System.identityHashCode(object) == objects.get(i)) {
9589                        return true;
9590                    }
9591                }
9592            }
9593            if (strings != null) {
9594                String flat = comp.flattenToString();
9595                for (int i=0; i<strings.size(); i++) {
9596                    if (flat.contains(strings.get(i))) {
9597                        return true;
9598                    }
9599                }
9600            }
9601            return false;
9602        }
9603    }
9604
9605    /**
9606     * There are three things that cmd can be:
9607     *  - a flattened component name that matches an existing activity
9608     *  - the cmd arg isn't the flattened component name of an existing activity:
9609     *    dump all activity whose component contains the cmd as a substring
9610     *  - A hex number of the ActivityRecord object instance.
9611     */
9612    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9613            int opti, boolean dumpAll) {
9614        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9615
9616        if ("all".equals(name)) {
9617            synchronized (this) {
9618                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9619                    activities.add(r1);
9620                }
9621            }
9622        } else if ("top".equals(name)) {
9623            synchronized (this) {
9624                final int N = mMainStack.mHistory.size();
9625                if (N > 0) {
9626                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9627                }
9628            }
9629        } else {
9630            ItemMatcher matcher = new ItemMatcher();
9631            matcher.build(name);
9632
9633            synchronized (this) {
9634                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9635                    if (matcher.match(r1, r1.intent.getComponent())) {
9636                        activities.add(r1);
9637                    }
9638                }
9639            }
9640        }
9641
9642        if (activities.size() <= 0) {
9643            return false;
9644        }
9645
9646        String[] newArgs = new String[args.length - opti];
9647        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9648
9649        TaskRecord lastTask = null;
9650        boolean needSep = false;
9651        for (int i=activities.size()-1; i>=0; i--) {
9652            ActivityRecord r = (ActivityRecord)activities.get(i);
9653            if (needSep) {
9654                pw.println();
9655            }
9656            needSep = true;
9657            synchronized (this) {
9658                if (lastTask != r.task) {
9659                    lastTask = r.task;
9660                    pw.print("TASK "); pw.print(lastTask.affinity);
9661                            pw.print(" id="); pw.println(lastTask.taskId);
9662                    if (dumpAll) {
9663                        lastTask.dump(pw, "  ");
9664                    }
9665                }
9666            }
9667            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9668        }
9669        return true;
9670    }
9671
9672    /**
9673     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9674     * there is a thread associated with the activity.
9675     */
9676    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9677            final ActivityRecord r, String[] args, boolean dumpAll) {
9678        String innerPrefix = prefix + "  ";
9679        synchronized (this) {
9680            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9681                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9682                    pw.print(" pid=");
9683                    if (r.app != null) pw.println(r.app.pid);
9684                    else pw.println("(not running)");
9685            if (dumpAll) {
9686                r.dump(pw, innerPrefix);
9687            }
9688        }
9689        if (r.app != null && r.app.thread != null) {
9690            // flush anything that is already in the PrintWriter since the thread is going
9691            // to write to the file descriptor directly
9692            pw.flush();
9693            try {
9694                TransferPipe tp = new TransferPipe();
9695                try {
9696                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9697                            r.appToken, innerPrefix, args);
9698                    tp.go(fd);
9699                } finally {
9700                    tp.kill();
9701                }
9702            } catch (IOException e) {
9703                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9704            } catch (RemoteException e) {
9705                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9706            }
9707        }
9708    }
9709
9710    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9711            int opti, boolean dumpAll, String dumpPackage) {
9712        boolean needSep = false;
9713        boolean onlyHistory = false;
9714
9715        if ("history".equals(dumpPackage)) {
9716            onlyHistory = true;
9717            dumpPackage = null;
9718        }
9719
9720        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9721        if (!onlyHistory && dumpAll) {
9722            if (mRegisteredReceivers.size() > 0) {
9723                boolean printed = false;
9724                Iterator it = mRegisteredReceivers.values().iterator();
9725                while (it.hasNext()) {
9726                    ReceiverList r = (ReceiverList)it.next();
9727                    if (dumpPackage != null && (r.app == null ||
9728                            !dumpPackage.equals(r.app.info.packageName))) {
9729                        continue;
9730                    }
9731                    if (!printed) {
9732                        pw.println("  Registered Receivers:");
9733                        needSep = true;
9734                        printed = true;
9735                    }
9736                    pw.print("  * "); pw.println(r);
9737                    r.dump(pw, "    ");
9738                }
9739            }
9740
9741            if (mReceiverResolver.dump(pw, needSep ?
9742                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9743                    "    ", dumpPackage, false)) {
9744                needSep = true;
9745            }
9746        }
9747
9748        for (BroadcastQueue q : mBroadcastQueues) {
9749            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9750        }
9751
9752        needSep = true;
9753
9754        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9755            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9756                if (needSep) {
9757                    pw.println();
9758                }
9759                needSep = true;
9760                pw.print("  Sticky broadcasts for user ");
9761                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9762                StringBuilder sb = new StringBuilder(128);
9763                for (Map.Entry<String, ArrayList<Intent>> ent
9764                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9765                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9766                    if (dumpAll) {
9767                        pw.println(":");
9768                        ArrayList<Intent> intents = ent.getValue();
9769                        final int N = intents.size();
9770                        for (int i=0; i<N; i++) {
9771                            sb.setLength(0);
9772                            sb.append("    Intent: ");
9773                            intents.get(i).toShortString(sb, false, true, false, false);
9774                            pw.println(sb.toString());
9775                            Bundle bundle = intents.get(i).getExtras();
9776                            if (bundle != null) {
9777                                pw.print("      ");
9778                                pw.println(bundle.toString());
9779                            }
9780                        }
9781                    } else {
9782                        pw.println("");
9783                    }
9784                }
9785            }
9786        }
9787
9788        if (!onlyHistory && dumpAll) {
9789            pw.println();
9790            for (BroadcastQueue queue : mBroadcastQueues) {
9791                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9792                        + queue.mBroadcastsScheduled);
9793            }
9794            pw.println("  mHandler:");
9795            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9796            needSep = true;
9797        }
9798
9799        return needSep;
9800    }
9801
9802    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9803            int opti, boolean dumpAll, String dumpPackage) {
9804        boolean needSep = true;
9805
9806        ItemMatcher matcher = new ItemMatcher();
9807        matcher.build(args, opti);
9808
9809        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9810
9811        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9812
9813        if (mLaunchingProviders.size() > 0) {
9814            boolean printed = false;
9815            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9816                ContentProviderRecord r = mLaunchingProviders.get(i);
9817                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9818                    continue;
9819                }
9820                if (!printed) {
9821                    if (needSep) pw.println(" ");
9822                    needSep = true;
9823                    pw.println("  Launching content providers:");
9824                    printed = true;
9825                }
9826                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9827                        pw.println(r);
9828            }
9829        }
9830
9831        if (mGrantedUriPermissions.size() > 0) {
9832            if (needSep) pw.println();
9833            needSep = true;
9834            pw.println("Granted Uri Permissions:");
9835            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9836                int uid = mGrantedUriPermissions.keyAt(i);
9837                HashMap<Uri, UriPermission> perms
9838                        = mGrantedUriPermissions.valueAt(i);
9839                pw.print("  * UID "); pw.print(uid);
9840                        pw.println(" holds:");
9841                for (UriPermission perm : perms.values()) {
9842                    pw.print("    "); pw.println(perm);
9843                    if (dumpAll) {
9844                        perm.dump(pw, "      ");
9845                    }
9846                }
9847            }
9848            needSep = true;
9849        }
9850
9851        return needSep;
9852    }
9853
9854    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9855            int opti, boolean dumpAll, String dumpPackage) {
9856        boolean needSep = false;
9857
9858        if (mIntentSenderRecords.size() > 0) {
9859            boolean printed = false;
9860            Iterator<WeakReference<PendingIntentRecord>> it
9861                    = mIntentSenderRecords.values().iterator();
9862            while (it.hasNext()) {
9863                WeakReference<PendingIntentRecord> ref = it.next();
9864                PendingIntentRecord rec = ref != null ? ref.get(): null;
9865                if (dumpPackage != null && (rec == null
9866                        || !dumpPackage.equals(rec.key.packageName))) {
9867                    continue;
9868                }
9869                if (!printed) {
9870                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9871                    printed = true;
9872                }
9873                needSep = true;
9874                if (rec != null) {
9875                    pw.print("  * "); pw.println(rec);
9876                    if (dumpAll) {
9877                        rec.dump(pw, "    ");
9878                    }
9879                } else {
9880                    pw.print("  * "); pw.println(ref);
9881                }
9882            }
9883        }
9884
9885        return needSep;
9886    }
9887
9888    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9889            String prefix, String label, boolean complete, boolean brief, boolean client,
9890            String dumpPackage) {
9891        TaskRecord lastTask = null;
9892        boolean needNL = false;
9893        final String innerPrefix = prefix + "      ";
9894        final String[] args = new String[0];
9895        for (int i=list.size()-1; i>=0; i--) {
9896            final ActivityRecord r = (ActivityRecord)list.get(i);
9897            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9898                continue;
9899            }
9900            final boolean full = !brief && (complete || !r.isInHistory());
9901            if (needNL) {
9902                pw.println(" ");
9903                needNL = false;
9904            }
9905            if (lastTask != r.task) {
9906                lastTask = r.task;
9907                pw.print(prefix);
9908                pw.print(full ? "* " : "  ");
9909                pw.println(lastTask);
9910                if (full) {
9911                    lastTask.dump(pw, prefix + "  ");
9912                } else if (complete) {
9913                    // Complete + brief == give a summary.  Isn't that obvious?!?
9914                    if (lastTask.intent != null) {
9915                        pw.print(prefix); pw.print("  ");
9916                                pw.println(lastTask.intent.toInsecureStringWithClip());
9917                    }
9918                }
9919            }
9920            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9921            pw.print(" #"); pw.print(i); pw.print(": ");
9922            pw.println(r);
9923            if (full) {
9924                r.dump(pw, innerPrefix);
9925            } else if (complete) {
9926                // Complete + brief == give a summary.  Isn't that obvious?!?
9927                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9928                if (r.app != null) {
9929                    pw.print(innerPrefix); pw.println(r.app);
9930                }
9931            }
9932            if (client && r.app != null && r.app.thread != null) {
9933                // flush anything that is already in the PrintWriter since the thread is going
9934                // to write to the file descriptor directly
9935                pw.flush();
9936                try {
9937                    TransferPipe tp = new TransferPipe();
9938                    try {
9939                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9940                                r.appToken, innerPrefix, args);
9941                        // Short timeout, since blocking here can
9942                        // deadlock with the application.
9943                        tp.go(fd, 2000);
9944                    } finally {
9945                        tp.kill();
9946                    }
9947                } catch (IOException e) {
9948                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9949                } catch (RemoteException e) {
9950                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9951                }
9952                needNL = true;
9953            }
9954        }
9955    }
9956
9957    private static String buildOomTag(String prefix, String space, int val, int base) {
9958        if (val == base) {
9959            if (space == null) return prefix;
9960            return prefix + "  ";
9961        }
9962        return prefix + "+" + Integer.toString(val-base);
9963    }
9964
9965    private static final int dumpProcessList(PrintWriter pw,
9966            ActivityManagerService service, List list,
9967            String prefix, String normalLabel, String persistentLabel,
9968            String dumpPackage) {
9969        int numPers = 0;
9970        final int N = list.size()-1;
9971        for (int i=N; i>=0; i--) {
9972            ProcessRecord r = (ProcessRecord)list.get(i);
9973            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9974                continue;
9975            }
9976            pw.println(String.format("%s%s #%2d: %s",
9977                    prefix, (r.persistent ? persistentLabel : normalLabel),
9978                    i, r.toString()));
9979            if (r.persistent) {
9980                numPers++;
9981            }
9982        }
9983        return numPers;
9984    }
9985
9986    private static final boolean dumpProcessOomList(PrintWriter pw,
9987            ActivityManagerService service, List<ProcessRecord> origList,
9988            String prefix, String normalLabel, String persistentLabel,
9989            boolean inclDetails, String dumpPackage) {
9990
9991        ArrayList<Pair<ProcessRecord, Integer>> list
9992                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9993        for (int i=0; i<origList.size(); i++) {
9994            ProcessRecord r = origList.get(i);
9995            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9996                continue;
9997            }
9998            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9999        }
10000
10001        if (list.size() <= 0) {
10002            return false;
10003        }
10004
10005        Comparator<Pair<ProcessRecord, Integer>> comparator
10006                = new Comparator<Pair<ProcessRecord, Integer>>() {
10007            @Override
10008            public int compare(Pair<ProcessRecord, Integer> object1,
10009                    Pair<ProcessRecord, Integer> object2) {
10010                if (object1.first.setAdj != object2.first.setAdj) {
10011                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10012                }
10013                if (object1.second.intValue() != object2.second.intValue()) {
10014                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10015                }
10016                return 0;
10017            }
10018        };
10019
10020        Collections.sort(list, comparator);
10021
10022        final long curRealtime = SystemClock.elapsedRealtime();
10023        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10024        final long curUptime = SystemClock.uptimeMillis();
10025        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10026
10027        for (int i=list.size()-1; i>=0; i--) {
10028            ProcessRecord r = list.get(i).first;
10029            String oomAdj;
10030            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10031                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10032            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10033                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10034            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10035                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10036            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10037                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10038            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10039                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10040            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10041                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10042            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10043                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10044            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10045                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10046            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10047                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10048            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10049                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10050            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10051                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10052            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10053                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10054            } else {
10055                oomAdj = Integer.toString(r.setAdj);
10056            }
10057            String schedGroup;
10058            switch (r.setSchedGroup) {
10059                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10060                    schedGroup = "B";
10061                    break;
10062                case Process.THREAD_GROUP_DEFAULT:
10063                    schedGroup = "F";
10064                    break;
10065                default:
10066                    schedGroup = Integer.toString(r.setSchedGroup);
10067                    break;
10068            }
10069            String foreground;
10070            if (r.foregroundActivities) {
10071                foreground = "A";
10072            } else if (r.foregroundServices) {
10073                foreground = "S";
10074            } else {
10075                foreground = " ";
10076            }
10077            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10078                    prefix, (r.persistent ? persistentLabel : normalLabel),
10079                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10080                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10081            if (r.adjSource != null || r.adjTarget != null) {
10082                pw.print(prefix);
10083                pw.print("    ");
10084                if (r.adjTarget instanceof ComponentName) {
10085                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10086                } else if (r.adjTarget != null) {
10087                    pw.print(r.adjTarget.toString());
10088                } else {
10089                    pw.print("{null}");
10090                }
10091                pw.print("<=");
10092                if (r.adjSource instanceof ProcessRecord) {
10093                    pw.print("Proc{");
10094                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10095                    pw.println("}");
10096                } else if (r.adjSource != null) {
10097                    pw.println(r.adjSource.toString());
10098                } else {
10099                    pw.println("{null}");
10100                }
10101            }
10102            if (inclDetails) {
10103                pw.print(prefix);
10104                pw.print("    ");
10105                pw.print("oom: max="); pw.print(r.maxAdj);
10106                pw.print(" hidden="); pw.print(r.hiddenAdj);
10107                pw.print(" client="); pw.print(r.clientHiddenAdj);
10108                pw.print(" empty="); pw.print(r.emptyAdj);
10109                pw.print(" curRaw="); pw.print(r.curRawAdj);
10110                pw.print(" setRaw="); pw.print(r.setRawAdj);
10111                pw.print(" cur="); pw.print(r.curAdj);
10112                pw.print(" set="); pw.println(r.setAdj);
10113                pw.print(prefix);
10114                pw.print("    ");
10115                pw.print("keeping="); pw.print(r.keeping);
10116                pw.print(" hidden="); pw.print(r.hidden);
10117                pw.print(" empty="); pw.print(r.empty);
10118                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10119
10120                if (!r.keeping) {
10121                    if (r.lastWakeTime != 0) {
10122                        long wtime;
10123                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10124                        synchronized (stats) {
10125                            wtime = stats.getProcessWakeTime(r.info.uid,
10126                                    r.pid, curRealtime);
10127                        }
10128                        long timeUsed = wtime - r.lastWakeTime;
10129                        pw.print(prefix);
10130                        pw.print("    ");
10131                        pw.print("keep awake over ");
10132                        TimeUtils.formatDuration(realtimeSince, pw);
10133                        pw.print(" used ");
10134                        TimeUtils.formatDuration(timeUsed, pw);
10135                        pw.print(" (");
10136                        pw.print((timeUsed*100)/realtimeSince);
10137                        pw.println("%)");
10138                    }
10139                    if (r.lastCpuTime != 0) {
10140                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10141                        pw.print(prefix);
10142                        pw.print("    ");
10143                        pw.print("run cpu over ");
10144                        TimeUtils.formatDuration(uptimeSince, pw);
10145                        pw.print(" used ");
10146                        TimeUtils.formatDuration(timeUsed, pw);
10147                        pw.print(" (");
10148                        pw.print((timeUsed*100)/uptimeSince);
10149                        pw.println("%)");
10150                    }
10151                }
10152            }
10153        }
10154        return true;
10155    }
10156
10157    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10158        ArrayList<ProcessRecord> procs;
10159        synchronized (this) {
10160            if (args != null && args.length > start
10161                    && args[start].charAt(0) != '-') {
10162                procs = new ArrayList<ProcessRecord>();
10163                int pid = -1;
10164                try {
10165                    pid = Integer.parseInt(args[start]);
10166                } catch (NumberFormatException e) {
10167
10168                }
10169                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10170                    ProcessRecord proc = mLruProcesses.get(i);
10171                    if (proc.pid == pid) {
10172                        procs.add(proc);
10173                    } else if (proc.processName.equals(args[start])) {
10174                        procs.add(proc);
10175                    }
10176                }
10177                if (procs.size() <= 0) {
10178                    pw.println("No process found for: " + args[start]);
10179                    return null;
10180                }
10181            } else {
10182                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10183            }
10184        }
10185        return procs;
10186    }
10187
10188    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10189            PrintWriter pw, String[] args) {
10190        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10191        if (procs == null) {
10192            return;
10193        }
10194
10195        long uptime = SystemClock.uptimeMillis();
10196        long realtime = SystemClock.elapsedRealtime();
10197        pw.println("Applications Graphics Acceleration Info:");
10198        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10199
10200        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10201            ProcessRecord r = procs.get(i);
10202            if (r.thread != null) {
10203                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10204                pw.flush();
10205                try {
10206                    TransferPipe tp = new TransferPipe();
10207                    try {
10208                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10209                        tp.go(fd);
10210                    } finally {
10211                        tp.kill();
10212                    }
10213                } catch (IOException e) {
10214                    pw.println("Failure while dumping the app: " + r);
10215                    pw.flush();
10216                } catch (RemoteException e) {
10217                    pw.println("Got a RemoteException while dumping the app " + r);
10218                    pw.flush();
10219                }
10220            }
10221        }
10222    }
10223
10224    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10225        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10226        if (procs == null) {
10227            return;
10228        }
10229
10230        pw.println("Applications Database Info:");
10231
10232        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10233            ProcessRecord r = procs.get(i);
10234            if (r.thread != null) {
10235                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10236                pw.flush();
10237                try {
10238                    TransferPipe tp = new TransferPipe();
10239                    try {
10240                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10241                        tp.go(fd);
10242                    } finally {
10243                        tp.kill();
10244                    }
10245                } catch (IOException e) {
10246                    pw.println("Failure while dumping the app: " + r);
10247                    pw.flush();
10248                } catch (RemoteException e) {
10249                    pw.println("Got a RemoteException while dumping the app " + r);
10250                    pw.flush();
10251                }
10252            }
10253        }
10254    }
10255
10256    final static class MemItem {
10257        final String label;
10258        final String shortLabel;
10259        final long pss;
10260        final int id;
10261        ArrayList<MemItem> subitems;
10262
10263        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10264            label = _label;
10265            shortLabel = _shortLabel;
10266            pss = _pss;
10267            id = _id;
10268        }
10269    }
10270
10271    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10272            boolean sort) {
10273        if (sort) {
10274            Collections.sort(items, new Comparator<MemItem>() {
10275                @Override
10276                public int compare(MemItem lhs, MemItem rhs) {
10277                    if (lhs.pss < rhs.pss) {
10278                        return 1;
10279                    } else if (lhs.pss > rhs.pss) {
10280                        return -1;
10281                    }
10282                    return 0;
10283                }
10284            });
10285        }
10286
10287        for (int i=0; i<items.size(); i++) {
10288            MemItem mi = items.get(i);
10289            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10290            if (mi.subitems != null) {
10291                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10292            }
10293        }
10294    }
10295
10296    // These are in KB.
10297    static final long[] DUMP_MEM_BUCKETS = new long[] {
10298        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10299        120*1024, 160*1024, 200*1024,
10300        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10301        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10302    };
10303
10304    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10305            boolean stackLike) {
10306        int start = label.lastIndexOf('.');
10307        if (start >= 0) start++;
10308        else start = 0;
10309        int end = label.length();
10310        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10311            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10312                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10313                out.append(bucket);
10314                out.append(stackLike ? "MB." : "MB ");
10315                out.append(label, start, end);
10316                return;
10317            }
10318        }
10319        out.append(memKB/1024);
10320        out.append(stackLike ? "MB." : "MB ");
10321        out.append(label, start, end);
10322    }
10323
10324    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10325            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10326            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10327            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10328            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10329    };
10330    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10331            "System", "Persistent", "Foreground",
10332            "Visible", "Perceptible", "Heavy Weight",
10333            "Backup", "A Services", "Home", "Previous",
10334            "B Services", "Background"
10335    };
10336
10337    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10338            PrintWriter pw, String prefix, String[] args, boolean brief,
10339            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10340        boolean dumpAll = false;
10341        boolean oomOnly = false;
10342
10343        int opti = 0;
10344        while (opti < args.length) {
10345            String opt = args[opti];
10346            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10347                break;
10348            }
10349            opti++;
10350            if ("-a".equals(opt)) {
10351                dumpAll = true;
10352            } else if ("--oom".equals(opt)) {
10353                oomOnly = true;
10354            } else if ("-h".equals(opt)) {
10355                pw.println("meminfo dump options: [-a] [--oom] [process]");
10356                pw.println("  -a: include all available information for each process.");
10357                pw.println("  --oom: only show processes organized by oom adj.");
10358                pw.println("If [process] is specified it can be the name or ");
10359                pw.println("pid of a specific process to dump.");
10360                return;
10361            } else {
10362                pw.println("Unknown argument: " + opt + "; use -h for help");
10363            }
10364        }
10365
10366        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10367        if (procs == null) {
10368            return;
10369        }
10370
10371        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10372        long uptime = SystemClock.uptimeMillis();
10373        long realtime = SystemClock.elapsedRealtime();
10374
10375        if (procs.size() == 1 || isCheckinRequest) {
10376            dumpAll = true;
10377        }
10378
10379        if (isCheckinRequest) {
10380            // short checkin version
10381            pw.println(uptime + "," + realtime);
10382            pw.flush();
10383        } else {
10384            pw.println("Applications Memory Usage (kB):");
10385            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10386        }
10387
10388        String[] innerArgs = new String[args.length-opti];
10389        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10390
10391        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10392        long nativePss=0, dalvikPss=0, otherPss=0;
10393        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10394
10395        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10396        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10397                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10398
10399        long totalPss = 0;
10400
10401        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10402            ProcessRecord r = procs.get(i);
10403            if (r.thread != null) {
10404                if (!isCheckinRequest && dumpAll) {
10405                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10406                    pw.flush();
10407                }
10408                Debug.MemoryInfo mi = null;
10409                if (dumpAll) {
10410                    try {
10411                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10412                    } catch (RemoteException e) {
10413                        if (!isCheckinRequest) {
10414                            pw.println("Got RemoteException!");
10415                            pw.flush();
10416                        }
10417                    }
10418                } else {
10419                    mi = new Debug.MemoryInfo();
10420                    Debug.getMemoryInfo(r.pid, mi);
10421                }
10422
10423                if (!isCheckinRequest && mi != null) {
10424                    long myTotalPss = mi.getTotalPss();
10425                    totalPss += myTotalPss;
10426                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10427                            r.processName, myTotalPss, 0);
10428                    procMems.add(pssItem);
10429
10430                    nativePss += mi.nativePss;
10431                    dalvikPss += mi.dalvikPss;
10432                    otherPss += mi.otherPss;
10433                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10434                        long mem = mi.getOtherPss(j);
10435                        miscPss[j] += mem;
10436                        otherPss -= mem;
10437                    }
10438
10439                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10440                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10441                                || oomIndex == (oomPss.length-1)) {
10442                            oomPss[oomIndex] += myTotalPss;
10443                            if (oomProcs[oomIndex] == null) {
10444                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10445                            }
10446                            oomProcs[oomIndex].add(pssItem);
10447                            break;
10448                        }
10449                    }
10450                }
10451            }
10452        }
10453
10454        if (!isCheckinRequest && procs.size() > 1) {
10455            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10456
10457            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10458            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10459            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10460            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10461                String label = Debug.MemoryInfo.getOtherLabel(j);
10462                catMems.add(new MemItem(label, label, miscPss[j], j));
10463            }
10464
10465            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10466            for (int j=0; j<oomPss.length; j++) {
10467                if (oomPss[j] != 0) {
10468                    String label = DUMP_MEM_OOM_LABEL[j];
10469                    MemItem item = new MemItem(label, label, oomPss[j],
10470                            DUMP_MEM_OOM_ADJ[j]);
10471                    item.subitems = oomProcs[j];
10472                    oomMems.add(item);
10473                }
10474            }
10475
10476            if (outTag != null || outStack != null) {
10477                if (outTag != null) {
10478                    appendMemBucket(outTag, totalPss, "total", false);
10479                }
10480                if (outStack != null) {
10481                    appendMemBucket(outStack, totalPss, "total", true);
10482                }
10483                boolean firstLine = true;
10484                for (int i=0; i<oomMems.size(); i++) {
10485                    MemItem miCat = oomMems.get(i);
10486                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10487                        continue;
10488                    }
10489                    if (miCat.id < ProcessList.SERVICE_ADJ
10490                            || miCat.id == ProcessList.HOME_APP_ADJ
10491                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10492                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10493                            outTag.append(" / ");
10494                        }
10495                        if (outStack != null) {
10496                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10497                                if (firstLine) {
10498                                    outStack.append(":");
10499                                    firstLine = false;
10500                                }
10501                                outStack.append("\n\t at ");
10502                            } else {
10503                                outStack.append("$");
10504                            }
10505                        }
10506                        for (int j=0; j<miCat.subitems.size(); j++) {
10507                            MemItem mi = miCat.subitems.get(j);
10508                            if (j > 0) {
10509                                if (outTag != null) {
10510                                    outTag.append(" ");
10511                                }
10512                                if (outStack != null) {
10513                                    outStack.append("$");
10514                                }
10515                            }
10516                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10517                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10518                            }
10519                            if (outStack != null) {
10520                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10521                            }
10522                        }
10523                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10524                            outStack.append("(");
10525                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10526                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10527                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10528                                    outStack.append(":");
10529                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10530                                }
10531                            }
10532                            outStack.append(")");
10533                        }
10534                    }
10535                }
10536            }
10537
10538            if (!brief && !oomOnly) {
10539                pw.println();
10540                pw.println("Total PSS by process:");
10541                dumpMemItems(pw, "  ", procMems, true);
10542                pw.println();
10543            }
10544            pw.println("Total PSS by OOM adjustment:");
10545            dumpMemItems(pw, "  ", oomMems, false);
10546            if (!oomOnly) {
10547                PrintWriter out = categoryPw != null ? categoryPw : pw;
10548                out.println();
10549                out.println("Total PSS by category:");
10550                dumpMemItems(out, "  ", catMems, true);
10551            }
10552            pw.println();
10553            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10554            final int[] SINGLE_LONG_FORMAT = new int[] {
10555                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10556            };
10557            long[] longOut = new long[1];
10558            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10559                    SINGLE_LONG_FORMAT, null, longOut, null);
10560            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10561            longOut[0] = 0;
10562            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10563                    SINGLE_LONG_FORMAT, null, longOut, null);
10564            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10565            longOut[0] = 0;
10566            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10567                    SINGLE_LONG_FORMAT, null, longOut, null);
10568            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10569            longOut[0] = 0;
10570            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10571                    SINGLE_LONG_FORMAT, null, longOut, null);
10572            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10573            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10574                    pw.print(shared); pw.println(" kB");
10575            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10576                    pw.print(voltile); pw.println(" kB volatile");
10577        }
10578    }
10579
10580    /**
10581     * Searches array of arguments for the specified string
10582     * @param args array of argument strings
10583     * @param value value to search for
10584     * @return true if the value is contained in the array
10585     */
10586    private static boolean scanArgs(String[] args, String value) {
10587        if (args != null) {
10588            for (String arg : args) {
10589                if (value.equals(arg)) {
10590                    return true;
10591                }
10592            }
10593        }
10594        return false;
10595    }
10596
10597    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10598            ContentProviderRecord cpr, boolean always) {
10599        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10600
10601        if (!inLaunching || always) {
10602            synchronized (cpr) {
10603                cpr.launchingApp = null;
10604                cpr.notifyAll();
10605            }
10606            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10607            String names[] = cpr.info.authority.split(";");
10608            for (int j = 0; j < names.length; j++) {
10609                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10610            }
10611        }
10612
10613        for (int i=0; i<cpr.connections.size(); i++) {
10614            ContentProviderConnection conn = cpr.connections.get(i);
10615            if (conn.waiting) {
10616                // If this connection is waiting for the provider, then we don't
10617                // need to mess with its process unless we are always removing
10618                // or for some reason the provider is not currently launching.
10619                if (inLaunching && !always) {
10620                    continue;
10621                }
10622            }
10623            ProcessRecord capp = conn.client;
10624            conn.dead = true;
10625            if (conn.stableCount > 0) {
10626                if (!capp.persistent && capp.thread != null
10627                        && capp.pid != 0
10628                        && capp.pid != MY_PID) {
10629                    Slog.i(TAG, "Kill " + capp.processName
10630                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10631                            + " in dying process " + (proc != null ? proc.processName : "??"));
10632                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10633                            capp.processName, capp.setAdj, "dying provider "
10634                                    + cpr.name.toShortString());
10635                    Process.killProcessQuiet(capp.pid);
10636                }
10637            } else if (capp.thread != null && conn.provider.provider != null) {
10638                try {
10639                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10640                } catch (RemoteException e) {
10641                }
10642                // In the protocol here, we don't expect the client to correctly
10643                // clean up this connection, we'll just remove it.
10644                cpr.connections.remove(i);
10645                conn.client.conProviders.remove(conn);
10646            }
10647        }
10648
10649        if (inLaunching && always) {
10650            mLaunchingProviders.remove(cpr);
10651        }
10652        return inLaunching;
10653    }
10654
10655    /**
10656     * Main code for cleaning up a process when it has gone away.  This is
10657     * called both as a result of the process dying, or directly when stopping
10658     * a process when running in single process mode.
10659     */
10660    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10661            boolean restarting, boolean allowRestart, int index) {
10662        if (index >= 0) {
10663            mLruProcesses.remove(index);
10664        }
10665
10666        mProcessesToGc.remove(app);
10667
10668        // Dismiss any open dialogs.
10669        if (app.crashDialog != null) {
10670            app.crashDialog.dismiss();
10671            app.crashDialog = null;
10672        }
10673        if (app.anrDialog != null) {
10674            app.anrDialog.dismiss();
10675            app.anrDialog = null;
10676        }
10677        if (app.waitDialog != null) {
10678            app.waitDialog.dismiss();
10679            app.waitDialog = null;
10680        }
10681
10682        app.crashing = false;
10683        app.notResponding = false;
10684
10685        app.resetPackageList();
10686        app.unlinkDeathRecipient();
10687        app.thread = null;
10688        app.forcingToForeground = null;
10689        app.foregroundServices = false;
10690        app.foregroundActivities = false;
10691        app.hasShownUi = false;
10692        app.hasAboveClient = false;
10693
10694        mServices.killServicesLocked(app, allowRestart);
10695
10696        boolean restart = false;
10697
10698        // Remove published content providers.
10699        if (!app.pubProviders.isEmpty()) {
10700            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10701            while (it.hasNext()) {
10702                ContentProviderRecord cpr = it.next();
10703
10704                final boolean always = app.bad || !allowRestart;
10705                if (removeDyingProviderLocked(app, cpr, always) || always) {
10706                    // We left the provider in the launching list, need to
10707                    // restart it.
10708                    restart = true;
10709                }
10710
10711                cpr.provider = null;
10712                cpr.proc = null;
10713            }
10714            app.pubProviders.clear();
10715        }
10716
10717        // Take care of any launching providers waiting for this process.
10718        if (checkAppInLaunchingProvidersLocked(app, false)) {
10719            restart = true;
10720        }
10721
10722        // Unregister from connected content providers.
10723        if (!app.conProviders.isEmpty()) {
10724            for (int i=0; i<app.conProviders.size(); i++) {
10725                ContentProviderConnection conn = app.conProviders.get(i);
10726                conn.provider.connections.remove(conn);
10727            }
10728            app.conProviders.clear();
10729        }
10730
10731        // At this point there may be remaining entries in mLaunchingProviders
10732        // where we were the only one waiting, so they are no longer of use.
10733        // Look for these and clean up if found.
10734        // XXX Commented out for now.  Trying to figure out a way to reproduce
10735        // the actual situation to identify what is actually going on.
10736        if (false) {
10737            for (int i=0; i<mLaunchingProviders.size(); i++) {
10738                ContentProviderRecord cpr = (ContentProviderRecord)
10739                        mLaunchingProviders.get(i);
10740                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10741                    synchronized (cpr) {
10742                        cpr.launchingApp = null;
10743                        cpr.notifyAll();
10744                    }
10745                }
10746            }
10747        }
10748
10749        skipCurrentReceiverLocked(app);
10750
10751        // Unregister any receivers.
10752        if (app.receivers.size() > 0) {
10753            Iterator<ReceiverList> it = app.receivers.iterator();
10754            while (it.hasNext()) {
10755                removeReceiverLocked(it.next());
10756            }
10757            app.receivers.clear();
10758        }
10759
10760        // If the app is undergoing backup, tell the backup manager about it
10761        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10762            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10763                    + mBackupTarget.appInfo + " died during backup");
10764            try {
10765                IBackupManager bm = IBackupManager.Stub.asInterface(
10766                        ServiceManager.getService(Context.BACKUP_SERVICE));
10767                bm.agentDisconnected(app.info.packageName);
10768            } catch (RemoteException e) {
10769                // can't happen; backup manager is local
10770            }
10771        }
10772
10773        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10774            ProcessChangeItem item = mPendingProcessChanges.get(i);
10775            if (item.pid == app.pid) {
10776                mPendingProcessChanges.remove(i);
10777                mAvailProcessChanges.add(item);
10778            }
10779        }
10780        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10781
10782        // If the caller is restarting this app, then leave it in its
10783        // current lists and let the caller take care of it.
10784        if (restarting) {
10785            return;
10786        }
10787
10788        if (!app.persistent || app.isolated) {
10789            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10790                    "Removing non-persistent process during cleanup: " + app);
10791            mProcessNames.remove(app.processName, app.uid);
10792            mIsolatedProcesses.remove(app.uid);
10793            if (mHeavyWeightProcess == app) {
10794                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10795                        mHeavyWeightProcess.userId, 0));
10796                mHeavyWeightProcess = null;
10797            }
10798        } else if (!app.removed) {
10799            // This app is persistent, so we need to keep its record around.
10800            // If it is not already on the pending app list, add it there
10801            // and start a new process for it.
10802            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10803                mPersistentStartingProcesses.add(app);
10804                restart = true;
10805            }
10806        }
10807        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10808                "Clean-up removing on hold: " + app);
10809        mProcessesOnHold.remove(app);
10810
10811        if (app == mHomeProcess) {
10812            mHomeProcess = null;
10813        }
10814        if (app == mPreviousProcess) {
10815            mPreviousProcess = null;
10816        }
10817
10818        if (restart && !app.isolated) {
10819            // We have components that still need to be running in the
10820            // process, so re-launch it.
10821            mProcessNames.put(app.processName, app.uid, app);
10822            startProcessLocked(app, "restart", app.processName);
10823        } else if (app.pid > 0 && app.pid != MY_PID) {
10824            // Goodbye!
10825            synchronized (mPidsSelfLocked) {
10826                mPidsSelfLocked.remove(app.pid);
10827                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10828            }
10829            app.setPid(0);
10830        }
10831    }
10832
10833    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10834        // Look through the content providers we are waiting to have launched,
10835        // and if any run in this process then either schedule a restart of
10836        // the process or kill the client waiting for it if this process has
10837        // gone bad.
10838        int NL = mLaunchingProviders.size();
10839        boolean restart = false;
10840        for (int i=0; i<NL; i++) {
10841            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10842            if (cpr.launchingApp == app) {
10843                if (!alwaysBad && !app.bad) {
10844                    restart = true;
10845                } else {
10846                    removeDyingProviderLocked(app, cpr, true);
10847                    // cpr should have been removed from mLaunchingProviders
10848                    NL = mLaunchingProviders.size();
10849                    i--;
10850                }
10851            }
10852        }
10853        return restart;
10854    }
10855
10856    // =========================================================
10857    // SERVICES
10858    // =========================================================
10859
10860    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10861            int flags) {
10862        enforceNotIsolatedCaller("getServices");
10863        synchronized (this) {
10864            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10865        }
10866    }
10867
10868    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10869        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10870        synchronized (this) {
10871            return mServices.getRunningServiceControlPanelLocked(name);
10872        }
10873    }
10874
10875    public ComponentName startService(IApplicationThread caller, Intent service,
10876            String resolvedType, int userId) {
10877        enforceNotIsolatedCaller("startService");
10878        // Refuse possible leaked file descriptors
10879        if (service != null && service.hasFileDescriptors() == true) {
10880            throw new IllegalArgumentException("File descriptors passed in Intent");
10881        }
10882
10883        if (DEBUG_SERVICE)
10884            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10885        synchronized(this) {
10886            final int callingPid = Binder.getCallingPid();
10887            final int callingUid = Binder.getCallingUid();
10888            checkValidCaller(callingUid, userId);
10889            final long origId = Binder.clearCallingIdentity();
10890            ComponentName res = mServices.startServiceLocked(caller, service,
10891                    resolvedType, callingPid, callingUid, userId);
10892            Binder.restoreCallingIdentity(origId);
10893            return res;
10894        }
10895    }
10896
10897    ComponentName startServiceInPackage(int uid,
10898            Intent service, String resolvedType, int userId) {
10899        synchronized(this) {
10900            if (DEBUG_SERVICE)
10901                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10902            final long origId = Binder.clearCallingIdentity();
10903            ComponentName res = mServices.startServiceLocked(null, service,
10904                    resolvedType, -1, uid, userId);
10905            Binder.restoreCallingIdentity(origId);
10906            return res;
10907        }
10908    }
10909
10910    public int stopService(IApplicationThread caller, Intent service,
10911            String resolvedType, int userId) {
10912        enforceNotIsolatedCaller("stopService");
10913        // Refuse possible leaked file descriptors
10914        if (service != null && service.hasFileDescriptors() == true) {
10915            throw new IllegalArgumentException("File descriptors passed in Intent");
10916        }
10917
10918        checkValidCaller(Binder.getCallingUid(), userId);
10919
10920        synchronized(this) {
10921            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10922        }
10923    }
10924
10925    public IBinder peekService(Intent service, String resolvedType) {
10926        enforceNotIsolatedCaller("peekService");
10927        // Refuse possible leaked file descriptors
10928        if (service != null && service.hasFileDescriptors() == true) {
10929            throw new IllegalArgumentException("File descriptors passed in Intent");
10930        }
10931        synchronized(this) {
10932            return mServices.peekServiceLocked(service, resolvedType);
10933        }
10934    }
10935
10936    public boolean stopServiceToken(ComponentName className, IBinder token,
10937            int startId) {
10938        synchronized(this) {
10939            return mServices.stopServiceTokenLocked(className, token, startId);
10940        }
10941    }
10942
10943    public void setServiceForeground(ComponentName className, IBinder token,
10944            int id, Notification notification, boolean removeNotification) {
10945        synchronized(this) {
10946            mServices.setServiceForegroundLocked(className, token, id, notification,
10947                    removeNotification);
10948        }
10949    }
10950
10951    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10952            boolean requireFull, String name, String callerPackage) {
10953        final int callingUserId = UserHandle.getUserId(callingUid);
10954        if (callingUserId != userId) {
10955            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10956                if ((requireFull || checkComponentPermission(
10957                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10958                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10959                        && checkComponentPermission(
10960                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10961                                callingPid, callingUid, -1, true)
10962                                != PackageManager.PERMISSION_GRANTED) {
10963                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10964                        // In this case, they would like to just execute as their
10965                        // owner user instead of failing.
10966                        userId = callingUserId;
10967                    } else {
10968                        StringBuilder builder = new StringBuilder(128);
10969                        builder.append("Permission Denial: ");
10970                        builder.append(name);
10971                        if (callerPackage != null) {
10972                            builder.append(" from ");
10973                            builder.append(callerPackage);
10974                        }
10975                        builder.append(" asks to run as user ");
10976                        builder.append(userId);
10977                        builder.append(" but is calling from user ");
10978                        builder.append(UserHandle.getUserId(callingUid));
10979                        builder.append("; this requires ");
10980                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10981                        if (!requireFull) {
10982                            builder.append(" or ");
10983                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10984                        }
10985                        String msg = builder.toString();
10986                        Slog.w(TAG, msg);
10987                        throw new SecurityException(msg);
10988                    }
10989                }
10990            }
10991            if (userId == UserHandle.USER_CURRENT
10992                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10993                // Note that we may be accessing this outside of a lock...
10994                // shouldn't be a big deal, if this is being called outside
10995                // of a locked context there is intrinsically a race with
10996                // the value the caller will receive and someone else changing it.
10997                userId = mCurrentUserId;
10998            }
10999            if (!allowAll && userId < 0) {
11000                throw new IllegalArgumentException(
11001                        "Call does not support special user #" + userId);
11002            }
11003        }
11004        return userId;
11005    }
11006
11007    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11008            String className, int flags) {
11009        boolean result = false;
11010        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11011            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11012                if (ActivityManager.checkUidPermission(
11013                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11014                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11015                    ComponentName comp = new ComponentName(aInfo.packageName, className);
11016                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
11017                            + " requests FLAG_SINGLE_USER, but app does not hold "
11018                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11019                    Slog.w(TAG, msg);
11020                    throw new SecurityException(msg);
11021                }
11022                result = true;
11023            }
11024        } else if (componentProcessName == aInfo.packageName) {
11025            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11026        } else if ("system".equals(componentProcessName)) {
11027            result = true;
11028        }
11029        if (DEBUG_MU) {
11030            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11031                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11032        }
11033        return result;
11034    }
11035
11036    public int bindService(IApplicationThread caller, IBinder token,
11037            Intent service, String resolvedType,
11038            IServiceConnection connection, int flags, int userId) {
11039        enforceNotIsolatedCaller("bindService");
11040        // Refuse possible leaked file descriptors
11041        if (service != null && service.hasFileDescriptors() == true) {
11042            throw new IllegalArgumentException("File descriptors passed in Intent");
11043        }
11044
11045        synchronized(this) {
11046            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11047                    connection, flags, userId);
11048        }
11049    }
11050
11051    public boolean unbindService(IServiceConnection connection) {
11052        synchronized (this) {
11053            return mServices.unbindServiceLocked(connection);
11054        }
11055    }
11056
11057    public void publishService(IBinder token, Intent intent, IBinder service) {
11058        // Refuse possible leaked file descriptors
11059        if (intent != null && intent.hasFileDescriptors() == true) {
11060            throw new IllegalArgumentException("File descriptors passed in Intent");
11061        }
11062
11063        synchronized(this) {
11064            if (!(token instanceof ServiceRecord)) {
11065                throw new IllegalArgumentException("Invalid service token");
11066            }
11067            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11068        }
11069    }
11070
11071    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11072        // Refuse possible leaked file descriptors
11073        if (intent != null && intent.hasFileDescriptors() == true) {
11074            throw new IllegalArgumentException("File descriptors passed in Intent");
11075        }
11076
11077        synchronized(this) {
11078            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11079        }
11080    }
11081
11082    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11083        synchronized(this) {
11084            if (!(token instanceof ServiceRecord)) {
11085                throw new IllegalArgumentException("Invalid service token");
11086            }
11087            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11088        }
11089    }
11090
11091    // =========================================================
11092    // BACKUP AND RESTORE
11093    // =========================================================
11094
11095    // Cause the target app to be launched if necessary and its backup agent
11096    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11097    // activity manager to announce its creation.
11098    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11099        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11100        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11101
11102        synchronized(this) {
11103            // !!! TODO: currently no check here that we're already bound
11104            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11105            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11106            synchronized (stats) {
11107                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11108            }
11109
11110            // Backup agent is now in use, its package can't be stopped.
11111            try {
11112                AppGlobals.getPackageManager().setPackageStoppedState(
11113                        app.packageName, false, UserHandle.getUserId(app.uid));
11114            } catch (RemoteException e) {
11115            } catch (IllegalArgumentException e) {
11116                Slog.w(TAG, "Failed trying to unstop package "
11117                        + app.packageName + ": " + e);
11118            }
11119
11120            BackupRecord r = new BackupRecord(ss, app, backupMode);
11121            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11122                    ? new ComponentName(app.packageName, app.backupAgentName)
11123                    : new ComponentName("android", "FullBackupAgent");
11124            // startProcessLocked() returns existing proc's record if it's already running
11125            ProcessRecord proc = startProcessLocked(app.processName, app,
11126                    false, 0, "backup", hostingName, false, false);
11127            if (proc == null) {
11128                Slog.e(TAG, "Unable to start backup agent process " + r);
11129                return false;
11130            }
11131
11132            r.app = proc;
11133            mBackupTarget = r;
11134            mBackupAppName = app.packageName;
11135
11136            // Try not to kill the process during backup
11137            updateOomAdjLocked(proc);
11138
11139            // If the process is already attached, schedule the creation of the backup agent now.
11140            // If it is not yet live, this will be done when it attaches to the framework.
11141            if (proc.thread != null) {
11142                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11143                try {
11144                    proc.thread.scheduleCreateBackupAgent(app,
11145                            compatibilityInfoForPackageLocked(app), backupMode);
11146                } catch (RemoteException e) {
11147                    // Will time out on the backup manager side
11148                }
11149            } else {
11150                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11151            }
11152            // Invariants: at this point, the target app process exists and the application
11153            // is either already running or in the process of coming up.  mBackupTarget and
11154            // mBackupAppName describe the app, so that when it binds back to the AM we
11155            // know that it's scheduled for a backup-agent operation.
11156        }
11157
11158        return true;
11159    }
11160
11161    // A backup agent has just come up
11162    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11163        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11164                + " = " + agent);
11165
11166        synchronized(this) {
11167            if (!agentPackageName.equals(mBackupAppName)) {
11168                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11169                return;
11170            }
11171        }
11172
11173        long oldIdent = Binder.clearCallingIdentity();
11174        try {
11175            IBackupManager bm = IBackupManager.Stub.asInterface(
11176                    ServiceManager.getService(Context.BACKUP_SERVICE));
11177            bm.agentConnected(agentPackageName, agent);
11178        } catch (RemoteException e) {
11179            // can't happen; the backup manager service is local
11180        } catch (Exception e) {
11181            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11182            e.printStackTrace();
11183        } finally {
11184            Binder.restoreCallingIdentity(oldIdent);
11185        }
11186    }
11187
11188    // done with this agent
11189    public void unbindBackupAgent(ApplicationInfo appInfo) {
11190        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11191        if (appInfo == null) {
11192            Slog.w(TAG, "unbind backup agent for null app");
11193            return;
11194        }
11195
11196        synchronized(this) {
11197            if (mBackupAppName == null) {
11198                Slog.w(TAG, "Unbinding backup agent with no active backup");
11199                return;
11200            }
11201
11202            if (!mBackupAppName.equals(appInfo.packageName)) {
11203                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11204                return;
11205            }
11206
11207            ProcessRecord proc = mBackupTarget.app;
11208            mBackupTarget = null;
11209            mBackupAppName = null;
11210
11211            // Not backing this app up any more; reset its OOM adjustment
11212            updateOomAdjLocked(proc);
11213
11214            // If the app crashed during backup, 'thread' will be null here
11215            if (proc.thread != null) {
11216                try {
11217                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11218                            compatibilityInfoForPackageLocked(appInfo));
11219                } catch (Exception e) {
11220                    Slog.e(TAG, "Exception when unbinding backup agent:");
11221                    e.printStackTrace();
11222                }
11223            }
11224        }
11225    }
11226    // =========================================================
11227    // BROADCASTS
11228    // =========================================================
11229
11230    private final List getStickiesLocked(String action, IntentFilter filter,
11231            List cur, int userId) {
11232        final ContentResolver resolver = mContext.getContentResolver();
11233        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11234        if (stickies == null) {
11235            return cur;
11236        }
11237        final ArrayList<Intent> list = stickies.get(action);
11238        if (list == null) {
11239            return cur;
11240        }
11241        int N = list.size();
11242        for (int i=0; i<N; i++) {
11243            Intent intent = list.get(i);
11244            if (filter.match(resolver, intent, true, TAG) >= 0) {
11245                if (cur == null) {
11246                    cur = new ArrayList<Intent>();
11247                }
11248                cur.add(intent);
11249            }
11250        }
11251        return cur;
11252    }
11253
11254    boolean isPendingBroadcastProcessLocked(int pid) {
11255        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11256                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11257    }
11258
11259    void skipPendingBroadcastLocked(int pid) {
11260            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11261            for (BroadcastQueue queue : mBroadcastQueues) {
11262                queue.skipPendingBroadcastLocked(pid);
11263            }
11264    }
11265
11266    // The app just attached; send any pending broadcasts that it should receive
11267    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11268        boolean didSomething = false;
11269        for (BroadcastQueue queue : mBroadcastQueues) {
11270            didSomething |= queue.sendPendingBroadcastsLocked(app);
11271        }
11272        return didSomething;
11273    }
11274
11275    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11276            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11277        enforceNotIsolatedCaller("registerReceiver");
11278        int callingUid;
11279        int callingPid;
11280        synchronized(this) {
11281            ProcessRecord callerApp = null;
11282            if (caller != null) {
11283                callerApp = getRecordForAppLocked(caller);
11284                if (callerApp == null) {
11285                    throw new SecurityException(
11286                            "Unable to find app for caller " + caller
11287                            + " (pid=" + Binder.getCallingPid()
11288                            + ") when registering receiver " + receiver);
11289                }
11290                if (callerApp.info.uid != Process.SYSTEM_UID &&
11291                        !callerApp.pkgList.contains(callerPackage)) {
11292                    throw new SecurityException("Given caller package " + callerPackage
11293                            + " is not running in process " + callerApp);
11294                }
11295                callingUid = callerApp.info.uid;
11296                callingPid = callerApp.pid;
11297            } else {
11298                callerPackage = null;
11299                callingUid = Binder.getCallingUid();
11300                callingPid = Binder.getCallingPid();
11301            }
11302
11303            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11304                    true, true, "registerReceiver", callerPackage);
11305
11306            List allSticky = null;
11307
11308            // Look for any matching sticky broadcasts...
11309            Iterator actions = filter.actionsIterator();
11310            if (actions != null) {
11311                while (actions.hasNext()) {
11312                    String action = (String)actions.next();
11313                    allSticky = getStickiesLocked(action, filter, allSticky,
11314                            UserHandle.USER_ALL);
11315                    allSticky = getStickiesLocked(action, filter, allSticky,
11316                            UserHandle.getUserId(callingUid));
11317                }
11318            } else {
11319                allSticky = getStickiesLocked(null, filter, allSticky,
11320                        UserHandle.USER_ALL);
11321                allSticky = getStickiesLocked(null, filter, allSticky,
11322                        UserHandle.getUserId(callingUid));
11323            }
11324
11325            // The first sticky in the list is returned directly back to
11326            // the client.
11327            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11328
11329            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11330                    + ": " + sticky);
11331
11332            if (receiver == null) {
11333                return sticky;
11334            }
11335
11336            ReceiverList rl
11337                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11338            if (rl == null) {
11339                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11340                        userId, receiver);
11341                if (rl.app != null) {
11342                    rl.app.receivers.add(rl);
11343                } else {
11344                    try {
11345                        receiver.asBinder().linkToDeath(rl, 0);
11346                    } catch (RemoteException e) {
11347                        return sticky;
11348                    }
11349                    rl.linkedToDeath = true;
11350                }
11351                mRegisteredReceivers.put(receiver.asBinder(), rl);
11352            } else if (rl.uid != callingUid) {
11353                throw new IllegalArgumentException(
11354                        "Receiver requested to register for uid " + callingUid
11355                        + " was previously registered for uid " + rl.uid);
11356            } else if (rl.pid != callingPid) {
11357                throw new IllegalArgumentException(
11358                        "Receiver requested to register for pid " + callingPid
11359                        + " was previously registered for pid " + rl.pid);
11360            } else if (rl.userId != userId) {
11361                throw new IllegalArgumentException(
11362                        "Receiver requested to register for user " + userId
11363                        + " was previously registered for user " + rl.userId);
11364            }
11365            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11366                    permission, callingUid, userId);
11367            rl.add(bf);
11368            if (!bf.debugCheck()) {
11369                Slog.w(TAG, "==> For Dynamic broadast");
11370            }
11371            mReceiverResolver.addFilter(bf);
11372
11373            // Enqueue broadcasts for all existing stickies that match
11374            // this filter.
11375            if (allSticky != null) {
11376                ArrayList receivers = new ArrayList();
11377                receivers.add(bf);
11378
11379                int N = allSticky.size();
11380                for (int i=0; i<N; i++) {
11381                    Intent intent = (Intent)allSticky.get(i);
11382                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11383                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11384                            null, -1, -1, null, receivers, null, 0, null, null,
11385                            false, true, true, -1);
11386                    queue.enqueueParallelBroadcastLocked(r);
11387                    queue.scheduleBroadcastsLocked();
11388                }
11389            }
11390
11391            return sticky;
11392        }
11393    }
11394
11395    public void unregisterReceiver(IIntentReceiver receiver) {
11396        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11397
11398        final long origId = Binder.clearCallingIdentity();
11399        try {
11400            boolean doTrim = false;
11401
11402            synchronized(this) {
11403                ReceiverList rl
11404                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11405                if (rl != null) {
11406                    if (rl.curBroadcast != null) {
11407                        BroadcastRecord r = rl.curBroadcast;
11408                        final boolean doNext = finishReceiverLocked(
11409                                receiver.asBinder(), r.resultCode, r.resultData,
11410                                r.resultExtras, r.resultAbort, true);
11411                        if (doNext) {
11412                            doTrim = true;
11413                            r.queue.processNextBroadcast(false);
11414                        }
11415                    }
11416
11417                    if (rl.app != null) {
11418                        rl.app.receivers.remove(rl);
11419                    }
11420                    removeReceiverLocked(rl);
11421                    if (rl.linkedToDeath) {
11422                        rl.linkedToDeath = false;
11423                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11424                    }
11425                }
11426            }
11427
11428            // If we actually concluded any broadcasts, we might now be able
11429            // to trim the recipients' apps from our working set
11430            if (doTrim) {
11431                trimApplications();
11432                return;
11433            }
11434
11435        } finally {
11436            Binder.restoreCallingIdentity(origId);
11437        }
11438    }
11439
11440    void removeReceiverLocked(ReceiverList rl) {
11441        mRegisteredReceivers.remove(rl.receiver.asBinder());
11442        int N = rl.size();
11443        for (int i=0; i<N; i++) {
11444            mReceiverResolver.removeFilter(rl.get(i));
11445        }
11446    }
11447
11448    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11449        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11450            ProcessRecord r = mLruProcesses.get(i);
11451            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11452                try {
11453                    r.thread.dispatchPackageBroadcast(cmd, packages);
11454                } catch (RemoteException ex) {
11455                }
11456            }
11457        }
11458    }
11459
11460    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11461            int[] users) {
11462        List<ResolveInfo> receivers = null;
11463        try {
11464            HashSet<ComponentName> singleUserReceivers = null;
11465            boolean scannedFirstReceivers = false;
11466            for (int user : users) {
11467                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11468                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11469                if (user != 0 && newReceivers != null) {
11470                    // If this is not the primary user, we need to check for
11471                    // any receivers that should be filtered out.
11472                    for (int i=0; i<newReceivers.size(); i++) {
11473                        ResolveInfo ri = newReceivers.get(i);
11474                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11475                            newReceivers.remove(i);
11476                            i--;
11477                        }
11478                    }
11479                }
11480                if (newReceivers != null && newReceivers.size() == 0) {
11481                    newReceivers = null;
11482                }
11483                if (receivers == null) {
11484                    receivers = newReceivers;
11485                } else if (newReceivers != null) {
11486                    // We need to concatenate the additional receivers
11487                    // found with what we have do far.  This would be easy,
11488                    // but we also need to de-dup any receivers that are
11489                    // singleUser.
11490                    if (!scannedFirstReceivers) {
11491                        // Collect any single user receivers we had already retrieved.
11492                        scannedFirstReceivers = true;
11493                        for (int i=0; i<receivers.size(); i++) {
11494                            ResolveInfo ri = receivers.get(i);
11495                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11496                                ComponentName cn = new ComponentName(
11497                                        ri.activityInfo.packageName, ri.activityInfo.name);
11498                                if (singleUserReceivers == null) {
11499                                    singleUserReceivers = new HashSet<ComponentName>();
11500                                }
11501                                singleUserReceivers.add(cn);
11502                            }
11503                        }
11504                    }
11505                    // Add the new results to the existing results, tracking
11506                    // and de-dupping single user receivers.
11507                    for (int i=0; i<newReceivers.size(); i++) {
11508                        ResolveInfo ri = newReceivers.get(i);
11509                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11510                            ComponentName cn = new ComponentName(
11511                                    ri.activityInfo.packageName, ri.activityInfo.name);
11512                            if (singleUserReceivers == null) {
11513                                singleUserReceivers = new HashSet<ComponentName>();
11514                            }
11515                            if (!singleUserReceivers.contains(cn)) {
11516                                singleUserReceivers.add(cn);
11517                                receivers.add(ri);
11518                            }
11519                        } else {
11520                            receivers.add(ri);
11521                        }
11522                    }
11523                }
11524            }
11525        } catch (RemoteException ex) {
11526            // pm is in same process, this will never happen.
11527        }
11528        return receivers;
11529    }
11530
11531    private final int broadcastIntentLocked(ProcessRecord callerApp,
11532            String callerPackage, Intent intent, String resolvedType,
11533            IIntentReceiver resultTo, int resultCode, String resultData,
11534            Bundle map, String requiredPermission,
11535            boolean ordered, boolean sticky, int callingPid, int callingUid,
11536            int userId) {
11537        intent = new Intent(intent);
11538
11539        // By default broadcasts do not go to stopped apps.
11540        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11541
11542        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11543            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11544            + " ordered=" + ordered + " userid=" + userId);
11545        if ((resultTo != null) && !ordered) {
11546            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11547        }
11548
11549        userId = handleIncomingUser(callingPid, callingUid, userId,
11550                true, false, "broadcast", callerPackage);
11551
11552        // Make sure that the user who is receiving this broadcast is started.
11553        // If not, we will just skip it.
11554        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11555            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11556                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11557                Slog.w(TAG, "Skipping broadcast of " + intent
11558                        + ": user " + userId + " is stopped");
11559                return ActivityManager.BROADCAST_SUCCESS;
11560            }
11561        }
11562
11563        /*
11564         * Prevent non-system code (defined here to be non-persistent
11565         * processes) from sending protected broadcasts.
11566         */
11567        int callingAppId = UserHandle.getAppId(callingUid);
11568        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11569            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11570            callingUid == 0) {
11571            // Always okay.
11572        } else if (callerApp == null || !callerApp.persistent) {
11573            try {
11574                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11575                        intent.getAction())) {
11576                    String msg = "Permission Denial: not allowed to send broadcast "
11577                            + intent.getAction() + " from pid="
11578                            + callingPid + ", uid=" + callingUid;
11579                    Slog.w(TAG, msg);
11580                    throw new SecurityException(msg);
11581                }
11582            } catch (RemoteException e) {
11583                Slog.w(TAG, "Remote exception", e);
11584                return ActivityManager.BROADCAST_SUCCESS;
11585            }
11586        }
11587
11588        // Handle special intents: if this broadcast is from the package
11589        // manager about a package being removed, we need to remove all of
11590        // its activities from the history stack.
11591        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11592                intent.getAction());
11593        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11594                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11595                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11596                || uidRemoved) {
11597            if (checkComponentPermission(
11598                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11599                    callingPid, callingUid, -1, true)
11600                    == PackageManager.PERMISSION_GRANTED) {
11601                if (uidRemoved) {
11602                    final Bundle intentExtras = intent.getExtras();
11603                    final int uid = intentExtras != null
11604                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11605                    if (uid >= 0) {
11606                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11607                        synchronized (bs) {
11608                            bs.removeUidStatsLocked(uid);
11609                        }
11610                    }
11611                } else {
11612                    // If resources are unavailable just force stop all
11613                    // those packages and flush the attribute cache as well.
11614                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11615                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11616                        if (list != null && (list.length > 0)) {
11617                            for (String pkg : list) {
11618                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11619                            }
11620                            sendPackageBroadcastLocked(
11621                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11622                        }
11623                    } else {
11624                        Uri data = intent.getData();
11625                        String ssp;
11626                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11627                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11628                                forceStopPackageLocked(ssp,
11629                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11630                                        false, userId);
11631                            }
11632                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11633                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11634                                        new String[] {ssp}, userId);
11635                            }
11636                        }
11637                    }
11638                }
11639            } else {
11640                String msg = "Permission Denial: " + intent.getAction()
11641                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11642                        + ", uid=" + callingUid + ")"
11643                        + " requires "
11644                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11645                Slog.w(TAG, msg);
11646                throw new SecurityException(msg);
11647            }
11648
11649        // Special case for adding a package: by default turn on compatibility
11650        // mode.
11651        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11652            Uri data = intent.getData();
11653            String ssp;
11654            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11655                mCompatModePackages.handlePackageAddedLocked(ssp,
11656                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11657            }
11658        }
11659
11660        /*
11661         * If this is the time zone changed action, queue up a message that will reset the timezone
11662         * of all currently running processes. This message will get queued up before the broadcast
11663         * happens.
11664         */
11665        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11666            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11667        }
11668
11669        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11670            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11671        }
11672
11673        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11674            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11675            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11676        }
11677
11678        // Add to the sticky list if requested.
11679        if (sticky) {
11680            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11681                    callingPid, callingUid)
11682                    != PackageManager.PERMISSION_GRANTED) {
11683                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11684                        + callingPid + ", uid=" + callingUid
11685                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11686                Slog.w(TAG, msg);
11687                throw new SecurityException(msg);
11688            }
11689            if (requiredPermission != null) {
11690                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11691                        + " and enforce permission " + requiredPermission);
11692                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11693            }
11694            if (intent.getComponent() != null) {
11695                throw new SecurityException(
11696                        "Sticky broadcasts can't target a specific component");
11697            }
11698            // We use userId directly here, since the "all" target is maintained
11699            // as a separate set of sticky broadcasts.
11700            if (userId != UserHandle.USER_ALL) {
11701                // But first, if this is not a broadcast to all users, then
11702                // make sure it doesn't conflict with an existing broadcast to
11703                // all users.
11704                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11705                        UserHandle.USER_ALL);
11706                if (stickies != null) {
11707                    ArrayList<Intent> list = stickies.get(intent.getAction());
11708                    if (list != null) {
11709                        int N = list.size();
11710                        int i;
11711                        for (i=0; i<N; i++) {
11712                            if (intent.filterEquals(list.get(i))) {
11713                                throw new IllegalArgumentException(
11714                                        "Sticky broadcast " + intent + " for user "
11715                                        + userId + " conflicts with existing global broadcast");
11716                            }
11717                        }
11718                    }
11719                }
11720            }
11721            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11722            if (stickies == null) {
11723                stickies = new HashMap<String, ArrayList<Intent>>();
11724                mStickyBroadcasts.put(userId, stickies);
11725            }
11726            ArrayList<Intent> list = stickies.get(intent.getAction());
11727            if (list == null) {
11728                list = new ArrayList<Intent>();
11729                stickies.put(intent.getAction(), list);
11730            }
11731            int N = list.size();
11732            int i;
11733            for (i=0; i<N; i++) {
11734                if (intent.filterEquals(list.get(i))) {
11735                    // This sticky already exists, replace it.
11736                    list.set(i, new Intent(intent));
11737                    break;
11738                }
11739            }
11740            if (i >= N) {
11741                list.add(new Intent(intent));
11742            }
11743        }
11744
11745        int[] users;
11746        if (userId == UserHandle.USER_ALL) {
11747            // Caller wants broadcast to go to all started users.
11748            users = mStartedUserArray;
11749        } else {
11750            // Caller wants broadcast to go to one specific user.
11751            users = new int[] {userId};
11752        }
11753
11754        // Figure out who all will receive this broadcast.
11755        List receivers = null;
11756        List<BroadcastFilter> registeredReceivers = null;
11757        // Need to resolve the intent to interested receivers...
11758        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11759                 == 0) {
11760            receivers = collectReceiverComponents(intent, resolvedType, users);
11761        }
11762        if (intent.getComponent() == null) {
11763            registeredReceivers = mReceiverResolver.queryIntent(intent,
11764                    resolvedType, false, userId);
11765        }
11766
11767        final boolean replacePending =
11768                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11769
11770        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11771                + " replacePending=" + replacePending);
11772
11773        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11774        if (!ordered && NR > 0) {
11775            // If we are not serializing this broadcast, then send the
11776            // registered receivers separately so they don't wait for the
11777            // components to be launched.
11778            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11779            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11780                    callerPackage, callingPid, callingUid, requiredPermission,
11781                    registeredReceivers, resultTo, resultCode, resultData, map,
11782                    ordered, sticky, false, userId);
11783            if (DEBUG_BROADCAST) Slog.v(
11784                    TAG, "Enqueueing parallel broadcast " + r);
11785            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11786            if (!replaced) {
11787                queue.enqueueParallelBroadcastLocked(r);
11788                queue.scheduleBroadcastsLocked();
11789            }
11790            registeredReceivers = null;
11791            NR = 0;
11792        }
11793
11794        // Merge into one list.
11795        int ir = 0;
11796        if (receivers != null) {
11797            // A special case for PACKAGE_ADDED: do not allow the package
11798            // being added to see this broadcast.  This prevents them from
11799            // using this as a back door to get run as soon as they are
11800            // installed.  Maybe in the future we want to have a special install
11801            // broadcast or such for apps, but we'd like to deliberately make
11802            // this decision.
11803            String skipPackages[] = null;
11804            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11805                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11806                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11807                Uri data = intent.getData();
11808                if (data != null) {
11809                    String pkgName = data.getSchemeSpecificPart();
11810                    if (pkgName != null) {
11811                        skipPackages = new String[] { pkgName };
11812                    }
11813                }
11814            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11815                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11816            }
11817            if (skipPackages != null && (skipPackages.length > 0)) {
11818                for (String skipPackage : skipPackages) {
11819                    if (skipPackage != null) {
11820                        int NT = receivers.size();
11821                        for (int it=0; it<NT; it++) {
11822                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11823                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11824                                receivers.remove(it);
11825                                it--;
11826                                NT--;
11827                            }
11828                        }
11829                    }
11830                }
11831            }
11832
11833            int NT = receivers != null ? receivers.size() : 0;
11834            int it = 0;
11835            ResolveInfo curt = null;
11836            BroadcastFilter curr = null;
11837            while (it < NT && ir < NR) {
11838                if (curt == null) {
11839                    curt = (ResolveInfo)receivers.get(it);
11840                }
11841                if (curr == null) {
11842                    curr = registeredReceivers.get(ir);
11843                }
11844                if (curr.getPriority() >= curt.priority) {
11845                    // Insert this broadcast record into the final list.
11846                    receivers.add(it, curr);
11847                    ir++;
11848                    curr = null;
11849                    it++;
11850                    NT++;
11851                } else {
11852                    // Skip to the next ResolveInfo in the final list.
11853                    it++;
11854                    curt = null;
11855                }
11856            }
11857        }
11858        while (ir < NR) {
11859            if (receivers == null) {
11860                receivers = new ArrayList();
11861            }
11862            receivers.add(registeredReceivers.get(ir));
11863            ir++;
11864        }
11865
11866        if ((receivers != null && receivers.size() > 0)
11867                || resultTo != null) {
11868            BroadcastQueue queue = broadcastQueueForIntent(intent);
11869            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11870                    callerPackage, callingPid, callingUid, requiredPermission,
11871                    receivers, resultTo, resultCode, resultData, map, ordered,
11872                    sticky, false, userId);
11873            if (DEBUG_BROADCAST) Slog.v(
11874                    TAG, "Enqueueing ordered broadcast " + r
11875                    + ": prev had " + queue.mOrderedBroadcasts.size());
11876            if (DEBUG_BROADCAST) {
11877                int seq = r.intent.getIntExtra("seq", -1);
11878                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11879            }
11880            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11881            if (!replaced) {
11882                queue.enqueueOrderedBroadcastLocked(r);
11883                queue.scheduleBroadcastsLocked();
11884            }
11885        }
11886
11887        return ActivityManager.BROADCAST_SUCCESS;
11888    }
11889
11890    final Intent verifyBroadcastLocked(Intent intent) {
11891        // Refuse possible leaked file descriptors
11892        if (intent != null && intent.hasFileDescriptors() == true) {
11893            throw new IllegalArgumentException("File descriptors passed in Intent");
11894        }
11895
11896        int flags = intent.getFlags();
11897
11898        if (!mProcessesReady) {
11899            // if the caller really truly claims to know what they're doing, go
11900            // ahead and allow the broadcast without launching any receivers
11901            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11902                intent = new Intent(intent);
11903                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11904            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11905                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11906                        + " before boot completion");
11907                throw new IllegalStateException("Cannot broadcast before boot completed");
11908            }
11909        }
11910
11911        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11912            throw new IllegalArgumentException(
11913                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11914        }
11915
11916        return intent;
11917    }
11918
11919    public final int broadcastIntent(IApplicationThread caller,
11920            Intent intent, String resolvedType, IIntentReceiver resultTo,
11921            int resultCode, String resultData, Bundle map,
11922            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11923        enforceNotIsolatedCaller("broadcastIntent");
11924        synchronized(this) {
11925            intent = verifyBroadcastLocked(intent);
11926
11927            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11928            final int callingPid = Binder.getCallingPid();
11929            final int callingUid = Binder.getCallingUid();
11930            final long origId = Binder.clearCallingIdentity();
11931            int res = broadcastIntentLocked(callerApp,
11932                    callerApp != null ? callerApp.info.packageName : null,
11933                    intent, resolvedType, resultTo,
11934                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11935                    callingPid, callingUid, userId);
11936            Binder.restoreCallingIdentity(origId);
11937            return res;
11938        }
11939    }
11940
11941    int broadcastIntentInPackage(String packageName, int uid,
11942            Intent intent, String resolvedType, IIntentReceiver resultTo,
11943            int resultCode, String resultData, Bundle map,
11944            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11945        synchronized(this) {
11946            intent = verifyBroadcastLocked(intent);
11947
11948            final long origId = Binder.clearCallingIdentity();
11949            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11950                    resultTo, resultCode, resultData, map, requiredPermission,
11951                    serialized, sticky, -1, uid, userId);
11952            Binder.restoreCallingIdentity(origId);
11953            return res;
11954        }
11955    }
11956
11957    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11958        // Refuse possible leaked file descriptors
11959        if (intent != null && intent.hasFileDescriptors() == true) {
11960            throw new IllegalArgumentException("File descriptors passed in Intent");
11961        }
11962
11963        userId = handleIncomingUser(Binder.getCallingPid(),
11964                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11965
11966        synchronized(this) {
11967            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11968                    != PackageManager.PERMISSION_GRANTED) {
11969                String msg = "Permission Denial: unbroadcastIntent() from pid="
11970                        + Binder.getCallingPid()
11971                        + ", uid=" + Binder.getCallingUid()
11972                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11973                Slog.w(TAG, msg);
11974                throw new SecurityException(msg);
11975            }
11976            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11977            if (stickies != null) {
11978                ArrayList<Intent> list = stickies.get(intent.getAction());
11979                if (list != null) {
11980                    int N = list.size();
11981                    int i;
11982                    for (i=0; i<N; i++) {
11983                        if (intent.filterEquals(list.get(i))) {
11984                            list.remove(i);
11985                            break;
11986                        }
11987                    }
11988                    if (list.size() <= 0) {
11989                        stickies.remove(intent.getAction());
11990                    }
11991                }
11992                if (stickies.size() <= 0) {
11993                    mStickyBroadcasts.remove(userId);
11994                }
11995            }
11996        }
11997    }
11998
11999    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12000            String resultData, Bundle resultExtras, boolean resultAbort,
12001            boolean explicit) {
12002        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12003        if (r == null) {
12004            Slog.w(TAG, "finishReceiver called but not found on queue");
12005            return false;
12006        }
12007
12008        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12009                explicit);
12010    }
12011
12012    public void finishReceiver(IBinder who, int resultCode, String resultData,
12013            Bundle resultExtras, boolean resultAbort) {
12014        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12015
12016        // Refuse possible leaked file descriptors
12017        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12018            throw new IllegalArgumentException("File descriptors passed in Bundle");
12019        }
12020
12021        final long origId = Binder.clearCallingIdentity();
12022        try {
12023            boolean doNext = false;
12024            BroadcastRecord r = null;
12025
12026            synchronized(this) {
12027                r = broadcastRecordForReceiverLocked(who);
12028                if (r != null) {
12029                    doNext = r.queue.finishReceiverLocked(r, resultCode,
12030                        resultData, resultExtras, resultAbort, true);
12031                }
12032            }
12033
12034            if (doNext) {
12035                r.queue.processNextBroadcast(false);
12036            }
12037            trimApplications();
12038        } finally {
12039            Binder.restoreCallingIdentity(origId);
12040        }
12041    }
12042
12043    // =========================================================
12044    // INSTRUMENTATION
12045    // =========================================================
12046
12047    public boolean startInstrumentation(ComponentName className,
12048            String profileFile, int flags, Bundle arguments,
12049            IInstrumentationWatcher watcher, int userId) {
12050        enforceNotIsolatedCaller("startInstrumentation");
12051        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12052                userId, false, true, "startInstrumentation", null);
12053        // Refuse possible leaked file descriptors
12054        if (arguments != null && arguments.hasFileDescriptors()) {
12055            throw new IllegalArgumentException("File descriptors passed in Bundle");
12056        }
12057
12058        synchronized(this) {
12059            InstrumentationInfo ii = null;
12060            ApplicationInfo ai = null;
12061            try {
12062                ii = mContext.getPackageManager().getInstrumentationInfo(
12063                    className, STOCK_PM_FLAGS);
12064                ai = AppGlobals.getPackageManager().getApplicationInfo(
12065                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12066            } catch (PackageManager.NameNotFoundException e) {
12067            } catch (RemoteException e) {
12068            }
12069            if (ii == null) {
12070                reportStartInstrumentationFailure(watcher, className,
12071                        "Unable to find instrumentation info for: " + className);
12072                return false;
12073            }
12074            if (ai == null) {
12075                reportStartInstrumentationFailure(watcher, className,
12076                        "Unable to find instrumentation target package: " + ii.targetPackage);
12077                return false;
12078            }
12079
12080            int match = mContext.getPackageManager().checkSignatures(
12081                    ii.targetPackage, ii.packageName);
12082            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12083                String msg = "Permission Denial: starting instrumentation "
12084                        + className + " from pid="
12085                        + Binder.getCallingPid()
12086                        + ", uid=" + Binder.getCallingPid()
12087                        + " not allowed because package " + ii.packageName
12088                        + " does not have a signature matching the target "
12089                        + ii.targetPackage;
12090                reportStartInstrumentationFailure(watcher, className, msg);
12091                throw new SecurityException(msg);
12092            }
12093
12094            final long origId = Binder.clearCallingIdentity();
12095            // Instrumentation can kill and relaunch even persistent processes
12096            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12097            ProcessRecord app = addAppLocked(ai, false);
12098            app.instrumentationClass = className;
12099            app.instrumentationInfo = ai;
12100            app.instrumentationProfileFile = profileFile;
12101            app.instrumentationArguments = arguments;
12102            app.instrumentationWatcher = watcher;
12103            app.instrumentationResultClass = className;
12104            Binder.restoreCallingIdentity(origId);
12105        }
12106
12107        return true;
12108    }
12109
12110    /**
12111     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12112     * error to the logs, but if somebody is watching, send the report there too.  This enables
12113     * the "am" command to report errors with more information.
12114     *
12115     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12116     * @param cn The component name of the instrumentation.
12117     * @param report The error report.
12118     */
12119    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12120            ComponentName cn, String report) {
12121        Slog.w(TAG, report);
12122        try {
12123            if (watcher != null) {
12124                Bundle results = new Bundle();
12125                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12126                results.putString("Error", report);
12127                watcher.instrumentationStatus(cn, -1, results);
12128            }
12129        } catch (RemoteException e) {
12130            Slog.w(TAG, e);
12131        }
12132    }
12133
12134    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12135        if (app.instrumentationWatcher != null) {
12136            try {
12137                // NOTE:  IInstrumentationWatcher *must* be oneway here
12138                app.instrumentationWatcher.instrumentationFinished(
12139                    app.instrumentationClass,
12140                    resultCode,
12141                    results);
12142            } catch (RemoteException e) {
12143            }
12144        }
12145        app.instrumentationWatcher = null;
12146        app.instrumentationClass = null;
12147        app.instrumentationInfo = null;
12148        app.instrumentationProfileFile = null;
12149        app.instrumentationArguments = null;
12150
12151        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12152    }
12153
12154    public void finishInstrumentation(IApplicationThread target,
12155            int resultCode, Bundle results) {
12156        int userId = UserHandle.getCallingUserId();
12157        // Refuse possible leaked file descriptors
12158        if (results != null && results.hasFileDescriptors()) {
12159            throw new IllegalArgumentException("File descriptors passed in Intent");
12160        }
12161
12162        synchronized(this) {
12163            ProcessRecord app = getRecordForAppLocked(target);
12164            if (app == null) {
12165                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12166                return;
12167            }
12168            final long origId = Binder.clearCallingIdentity();
12169            finishInstrumentationLocked(app, resultCode, results);
12170            Binder.restoreCallingIdentity(origId);
12171        }
12172    }
12173
12174    // =========================================================
12175    // CONFIGURATION
12176    // =========================================================
12177
12178    public ConfigurationInfo getDeviceConfigurationInfo() {
12179        ConfigurationInfo config = new ConfigurationInfo();
12180        synchronized (this) {
12181            config.reqTouchScreen = mConfiguration.touchscreen;
12182            config.reqKeyboardType = mConfiguration.keyboard;
12183            config.reqNavigation = mConfiguration.navigation;
12184            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12185                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12186                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12187            }
12188            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12189                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12190                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12191            }
12192            config.reqGlEsVersion = GL_ES_VERSION;
12193        }
12194        return config;
12195    }
12196
12197    public Configuration getConfiguration() {
12198        Configuration ci;
12199        synchronized(this) {
12200            ci = new Configuration(mConfiguration);
12201        }
12202        return ci;
12203    }
12204
12205    public void updatePersistentConfiguration(Configuration values) {
12206        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12207                "updateConfiguration()");
12208        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12209                "updateConfiguration()");
12210        if (values == null) {
12211            throw new NullPointerException("Configuration must not be null");
12212        }
12213
12214        synchronized(this) {
12215            final long origId = Binder.clearCallingIdentity();
12216            updateConfigurationLocked(values, null, true, false);
12217            Binder.restoreCallingIdentity(origId);
12218        }
12219    }
12220
12221    public void updateConfiguration(Configuration values) {
12222        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12223                "updateConfiguration()");
12224
12225        synchronized(this) {
12226            if (values == null && mWindowManager != null) {
12227                // sentinel: fetch the current configuration from the window manager
12228                values = mWindowManager.computeNewConfiguration();
12229            }
12230
12231            if (mWindowManager != null) {
12232                mProcessList.applyDisplaySize(mWindowManager);
12233            }
12234
12235            final long origId = Binder.clearCallingIdentity();
12236            if (values != null) {
12237                Settings.System.clearConfiguration(values);
12238            }
12239            updateConfigurationLocked(values, null, false, false);
12240            Binder.restoreCallingIdentity(origId);
12241        }
12242    }
12243
12244    /**
12245     * Do either or both things: (1) change the current configuration, and (2)
12246     * make sure the given activity is running with the (now) current
12247     * configuration.  Returns true if the activity has been left running, or
12248     * false if <var>starting</var> is being destroyed to match the new
12249     * configuration.
12250     * @param persistent TODO
12251     */
12252    boolean updateConfigurationLocked(Configuration values,
12253            ActivityRecord starting, boolean persistent, boolean initLocale) {
12254        // do nothing if we are headless
12255        if (mHeadless) return true;
12256
12257        int changes = 0;
12258
12259        boolean kept = true;
12260
12261        if (values != null) {
12262            Configuration newConfig = new Configuration(mConfiguration);
12263            changes = newConfig.updateFrom(values);
12264            if (changes != 0) {
12265                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12266                    Slog.i(TAG, "Updating configuration to: " + values);
12267                }
12268
12269                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12270
12271                if (values.locale != null && !initLocale) {
12272                    saveLocaleLocked(values.locale,
12273                                     !values.locale.equals(mConfiguration.locale),
12274                                     values.userSetLocale);
12275                }
12276
12277                mConfigurationSeq++;
12278                if (mConfigurationSeq <= 0) {
12279                    mConfigurationSeq = 1;
12280                }
12281                newConfig.seq = mConfigurationSeq;
12282                mConfiguration = newConfig;
12283                Slog.i(TAG, "Config changed: " + newConfig);
12284
12285                final Configuration configCopy = new Configuration(mConfiguration);
12286
12287                // TODO: If our config changes, should we auto dismiss any currently
12288                // showing dialogs?
12289                mShowDialogs = shouldShowDialogs(newConfig);
12290
12291                AttributeCache ac = AttributeCache.instance();
12292                if (ac != null) {
12293                    ac.updateConfiguration(configCopy);
12294                }
12295
12296                // Make sure all resources in our process are updated
12297                // right now, so that anyone who is going to retrieve
12298                // resource values after we return will be sure to get
12299                // the new ones.  This is especially important during
12300                // boot, where the first config change needs to guarantee
12301                // all resources have that config before following boot
12302                // code is executed.
12303                mSystemThread.applyConfigurationToResources(configCopy);
12304
12305                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12306                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12307                    msg.obj = new Configuration(configCopy);
12308                    mHandler.sendMessage(msg);
12309                }
12310
12311                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12312                    ProcessRecord app = mLruProcesses.get(i);
12313                    try {
12314                        if (app.thread != null) {
12315                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12316                                    + app.processName + " new config " + mConfiguration);
12317                            app.thread.scheduleConfigurationChanged(configCopy);
12318                        }
12319                    } catch (Exception e) {
12320                    }
12321                }
12322                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12323                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12324                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12325                        | Intent.FLAG_RECEIVER_FOREGROUND);
12326                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12327                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12328                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12329                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12330                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12331                    broadcastIntentLocked(null, null, intent,
12332                            null, null, 0, null, null,
12333                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12334                }
12335            }
12336        }
12337
12338        if (changes != 0 && starting == null) {
12339            // If the configuration changed, and the caller is not already
12340            // in the process of starting an activity, then find the top
12341            // activity to check if its configuration needs to change.
12342            starting = mMainStack.topRunningActivityLocked(null);
12343        }
12344
12345        if (starting != null) {
12346            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12347            // And we need to make sure at this point that all other activities
12348            // are made visible with the correct configuration.
12349            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12350        }
12351
12352        if (values != null && mWindowManager != null) {
12353            mWindowManager.setNewConfiguration(mConfiguration);
12354        }
12355
12356        return kept;
12357    }
12358
12359    /**
12360     * Decide based on the configuration whether we should shouw the ANR,
12361     * crash, etc dialogs.  The idea is that if there is no affordnace to
12362     * press the on-screen buttons, we shouldn't show the dialog.
12363     *
12364     * A thought: SystemUI might also want to get told about this, the Power
12365     * dialog / global actions also might want different behaviors.
12366     */
12367    private static final boolean shouldShowDialogs(Configuration config) {
12368        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12369                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12370    }
12371
12372    /**
12373     * Save the locale.  You must be inside a synchronized (this) block.
12374     */
12375    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12376        if(isDiff) {
12377            SystemProperties.set("user.language", l.getLanguage());
12378            SystemProperties.set("user.region", l.getCountry());
12379        }
12380
12381        if(isPersist) {
12382            SystemProperties.set("persist.sys.language", l.getLanguage());
12383            SystemProperties.set("persist.sys.country", l.getCountry());
12384            SystemProperties.set("persist.sys.localevar", l.getVariant());
12385        }
12386    }
12387
12388    @Override
12389    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12390        ActivityRecord srec = ActivityRecord.forToken(token);
12391        return srec != null && srec.task.affinity != null &&
12392                srec.task.affinity.equals(destAffinity);
12393    }
12394
12395    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12396            Intent resultData) {
12397        ComponentName dest = destIntent.getComponent();
12398
12399        synchronized (this) {
12400            ActivityRecord srec = ActivityRecord.forToken(token);
12401            if (srec == null) {
12402                return false;
12403            }
12404            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12405            final int start = history.indexOf(srec);
12406            if (start < 0) {
12407                // Current activity is not in history stack; do nothing.
12408                return false;
12409            }
12410            int finishTo = start - 1;
12411            ActivityRecord parent = null;
12412            boolean foundParentInTask = false;
12413            if (dest != null) {
12414                TaskRecord tr = srec.task;
12415                for (int i = start - 1; i >= 0; i--) {
12416                    ActivityRecord r = history.get(i);
12417                    if (tr != r.task) {
12418                        // Couldn't find parent in the same task; stop at the one above this.
12419                        // (Root of current task; in-app "home" behavior)
12420                        // Always at least finish the current activity.
12421                        finishTo = Math.min(start - 1, i + 1);
12422                        parent = history.get(finishTo);
12423                        break;
12424                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12425                            r.info.name.equals(dest.getClassName())) {
12426                        finishTo = i;
12427                        parent = r;
12428                        foundParentInTask = true;
12429                        break;
12430                    }
12431                }
12432            }
12433
12434            if (mController != null) {
12435                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12436                if (next != null) {
12437                    // ask watcher if this is allowed
12438                    boolean resumeOK = true;
12439                    try {
12440                        resumeOK = mController.activityResuming(next.packageName);
12441                    } catch (RemoteException e) {
12442                        mController = null;
12443                    }
12444
12445                    if (!resumeOK) {
12446                        return false;
12447                    }
12448                }
12449            }
12450            final long origId = Binder.clearCallingIdentity();
12451            for (int i = start; i > finishTo; i--) {
12452                ActivityRecord r = history.get(i);
12453                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12454                        "navigate-up", true);
12455                // Only return the supplied result for the first activity finished
12456                resultCode = Activity.RESULT_CANCELED;
12457                resultData = null;
12458            }
12459
12460            if (parent != null && foundParentInTask) {
12461                final int parentLaunchMode = parent.info.launchMode;
12462                final int destIntentFlags = destIntent.getFlags();
12463                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12464                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12465                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12466                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12467                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12468                } else {
12469                    try {
12470                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12471                                destIntent.getComponent(), 0, srec.userId);
12472                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12473                                null, aInfo, parent.appToken, null,
12474                                0, -1, parent.launchedFromUid, 0, null, true, null);
12475                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12476                    } catch (RemoteException e) {
12477                        foundParentInTask = false;
12478                    }
12479                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12480                            resultData, "navigate-up", true);
12481                }
12482            }
12483            Binder.restoreCallingIdentity(origId);
12484            return foundParentInTask;
12485        }
12486    }
12487
12488    public int getLaunchedFromUid(IBinder activityToken) {
12489        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12490        if (srec == null) {
12491            return -1;
12492        }
12493        return srec.launchedFromUid;
12494    }
12495
12496    // =========================================================
12497    // LIFETIME MANAGEMENT
12498    // =========================================================
12499
12500    // Returns which broadcast queue the app is the current [or imminent] receiver
12501    // on, or 'null' if the app is not an active broadcast recipient.
12502    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12503        BroadcastRecord r = app.curReceiver;
12504        if (r != null) {
12505            return r.queue;
12506        }
12507
12508        // It's not the current receiver, but it might be starting up to become one
12509        synchronized (this) {
12510            for (BroadcastQueue queue : mBroadcastQueues) {
12511                r = queue.mPendingBroadcast;
12512                if (r != null && r.curApp == app) {
12513                    // found it; report which queue it's in
12514                    return queue;
12515                }
12516            }
12517        }
12518
12519        return null;
12520    }
12521
12522    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12523            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12524        if (mAdjSeq == app.adjSeq) {
12525            // This adjustment has already been computed.  If we are calling
12526            // from the top, we may have already computed our adjustment with
12527            // an earlier hidden adjustment that isn't really for us... if
12528            // so, use the new hidden adjustment.
12529            if (!recursed && app.hidden) {
12530                if (app.hasActivities) {
12531                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12532                } else if (app.hasClientActivities) {
12533                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12534                } else {
12535                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12536                }
12537            }
12538            return app.curRawAdj;
12539        }
12540
12541        if (app.thread == null) {
12542            app.adjSeq = mAdjSeq;
12543            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12544            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12545        }
12546
12547        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12548        app.adjSource = null;
12549        app.adjTarget = null;
12550        app.empty = false;
12551        app.hidden = false;
12552        app.hasClientActivities = false;
12553
12554        final int activitiesSize = app.activities.size();
12555
12556        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12557            // The max adjustment doesn't allow this app to be anything
12558            // below foreground, so it is not worth doing work for it.
12559            app.adjType = "fixed";
12560            app.adjSeq = mAdjSeq;
12561            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12562            app.hasActivities = false;
12563            app.foregroundActivities = false;
12564            app.keeping = true;
12565            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12566            // System process can do UI, and when they do we want to have
12567            // them trim their memory after the user leaves the UI.  To
12568            // facilitate this, here we need to determine whether or not it
12569            // is currently showing UI.
12570            app.systemNoUi = true;
12571            if (app == TOP_APP) {
12572                app.systemNoUi = false;
12573                app.hasActivities = true;
12574            } else if (activitiesSize > 0) {
12575                for (int j = 0; j < activitiesSize; j++) {
12576                    final ActivityRecord r = app.activities.get(j);
12577                    if (r.visible) {
12578                        app.systemNoUi = false;
12579                    }
12580                    if (r.app == app) {
12581                        app.hasActivities = true;
12582                    }
12583                }
12584            }
12585            return (app.curAdj=app.maxAdj);
12586        }
12587
12588        app.keeping = false;
12589        app.systemNoUi = false;
12590        app.hasActivities = false;
12591
12592        // Determine the importance of the process, starting with most
12593        // important to least, and assign an appropriate OOM adjustment.
12594        int adj;
12595        int schedGroup;
12596        boolean foregroundActivities = false;
12597        boolean interesting = false;
12598        BroadcastQueue queue;
12599        if (app == TOP_APP) {
12600            // The last app on the list is the foreground app.
12601            adj = ProcessList.FOREGROUND_APP_ADJ;
12602            schedGroup = Process.THREAD_GROUP_DEFAULT;
12603            app.adjType = "top-activity";
12604            foregroundActivities = true;
12605            interesting = true;
12606            app.hasActivities = true;
12607        } else if (app.instrumentationClass != null) {
12608            // Don't want to kill running instrumentation.
12609            adj = ProcessList.FOREGROUND_APP_ADJ;
12610            schedGroup = Process.THREAD_GROUP_DEFAULT;
12611            app.adjType = "instrumentation";
12612            interesting = true;
12613        } else if ((queue = isReceivingBroadcast(app)) != null) {
12614            // An app that is currently receiving a broadcast also
12615            // counts as being in the foreground for OOM killer purposes.
12616            // It's placed in a sched group based on the nature of the
12617            // broadcast as reflected by which queue it's active in.
12618            adj = ProcessList.FOREGROUND_APP_ADJ;
12619            schedGroup = (queue == mFgBroadcastQueue)
12620                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12621            app.adjType = "broadcast";
12622        } else if (app.executingServices.size() > 0) {
12623            // An app that is currently executing a service callback also
12624            // counts as being in the foreground.
12625            adj = ProcessList.FOREGROUND_APP_ADJ;
12626            schedGroup = Process.THREAD_GROUP_DEFAULT;
12627            app.adjType = "exec-service";
12628        } else {
12629            // Assume process is hidden (has activities); we will correct
12630            // later if this is not the case.
12631            adj = hiddenAdj;
12632            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12633            app.hidden = true;
12634            app.adjType = "bg-act";
12635        }
12636
12637        boolean hasStoppingActivities = false;
12638
12639        // Examine all activities if not already foreground.
12640        if (!foregroundActivities && activitiesSize > 0) {
12641            for (int j = 0; j < activitiesSize; j++) {
12642                final ActivityRecord r = app.activities.get(j);
12643                if (r.visible) {
12644                    // App has a visible activity; only upgrade adjustment.
12645                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12646                        adj = ProcessList.VISIBLE_APP_ADJ;
12647                        app.adjType = "visible";
12648                    }
12649                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12650                    app.hidden = false;
12651                    app.hasActivities = true;
12652                    foregroundActivities = true;
12653                    break;
12654                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12655                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12656                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12657                        app.adjType = "pausing";
12658                    }
12659                    app.hidden = false;
12660                    foregroundActivities = true;
12661                } else if (r.state == ActivityState.STOPPING) {
12662                    // We will apply the actual adjustment later, because
12663                    // we want to allow this process to immediately go through
12664                    // any memory trimming that is in effect.
12665                    app.hidden = false;
12666                    foregroundActivities = true;
12667                    hasStoppingActivities = true;
12668                }
12669                if (r.app == app) {
12670                    app.hasActivities = true;
12671                }
12672            }
12673        }
12674
12675        if (adj == hiddenAdj && !app.hasActivities) {
12676            if (app.hasClientActivities) {
12677                adj = clientHiddenAdj;
12678                app.adjType = "bg-client-act";
12679            } else {
12680                // Whoops, this process is completely empty as far as we know
12681                // at this point.
12682                adj = emptyAdj;
12683                app.empty = true;
12684                app.adjType = "bg-empty";
12685            }
12686        }
12687
12688        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12689            if (app.foregroundServices) {
12690                // The user is aware of this app, so make it visible.
12691                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12692                app.hidden = false;
12693                app.adjType = "fg-service";
12694                schedGroup = Process.THREAD_GROUP_DEFAULT;
12695            } else if (app.forcingToForeground != null) {
12696                // The user is aware of this app, so make it visible.
12697                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12698                app.hidden = false;
12699                app.adjType = "force-fg";
12700                app.adjSource = app.forcingToForeground;
12701                schedGroup = Process.THREAD_GROUP_DEFAULT;
12702            }
12703        }
12704
12705        if (app.foregroundServices) {
12706            interesting = true;
12707        }
12708
12709        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12710            // We don't want to kill the current heavy-weight process.
12711            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12712            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12713            app.hidden = false;
12714            app.adjType = "heavy";
12715        }
12716
12717        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12718            // This process is hosting what we currently consider to be the
12719            // home app, so we don't want to let it go into the background.
12720            adj = ProcessList.HOME_APP_ADJ;
12721            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12722            app.hidden = false;
12723            app.adjType = "home";
12724        }
12725
12726        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12727                && app.activities.size() > 0) {
12728            // This was the previous process that showed UI to the user.
12729            // We want to try to keep it around more aggressively, to give
12730            // a good experience around switching between two apps.
12731            adj = ProcessList.PREVIOUS_APP_ADJ;
12732            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12733            app.hidden = false;
12734            app.adjType = "previous";
12735        }
12736
12737        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12738                + " reason=" + app.adjType);
12739
12740        // By default, we use the computed adjustment.  It may be changed if
12741        // there are applications dependent on our services or providers, but
12742        // this gives us a baseline and makes sure we don't get into an
12743        // infinite recursion.
12744        app.adjSeq = mAdjSeq;
12745        app.curRawAdj = app.nonStoppingAdj = adj;
12746
12747        if (mBackupTarget != null && app == mBackupTarget.app) {
12748            // If possible we want to avoid killing apps while they're being backed up
12749            if (adj > ProcessList.BACKUP_APP_ADJ) {
12750                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12751                adj = ProcessList.BACKUP_APP_ADJ;
12752                app.adjType = "backup";
12753                app.hidden = false;
12754            }
12755        }
12756
12757        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12758                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12759            final long now = SystemClock.uptimeMillis();
12760            // This process is more important if the top activity is
12761            // bound to the service.
12762            Iterator<ServiceRecord> jt = app.services.iterator();
12763            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12764                ServiceRecord s = jt.next();
12765                if (s.startRequested) {
12766                    if (app.hasShownUi && app != mHomeProcess) {
12767                        // If this process has shown some UI, let it immediately
12768                        // go to the LRU list because it may be pretty heavy with
12769                        // UI stuff.  We'll tag it with a label just to help
12770                        // debug and understand what is going on.
12771                        if (adj > ProcessList.SERVICE_ADJ) {
12772                            app.adjType = "started-bg-ui-services";
12773                        }
12774                    } else {
12775                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12776                            // This service has seen some activity within
12777                            // recent memory, so we will keep its process ahead
12778                            // of the background processes.
12779                            if (adj > ProcessList.SERVICE_ADJ) {
12780                                adj = ProcessList.SERVICE_ADJ;
12781                                app.adjType = "started-services";
12782                                app.hidden = false;
12783                            }
12784                        }
12785                        // If we have let the service slide into the background
12786                        // state, still have some text describing what it is doing
12787                        // even though the service no longer has an impact.
12788                        if (adj > ProcessList.SERVICE_ADJ) {
12789                            app.adjType = "started-bg-services";
12790                        }
12791                    }
12792                    // Don't kill this process because it is doing work; it
12793                    // has said it is doing work.
12794                    app.keeping = true;
12795                }
12796                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12797                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12798                    Iterator<ArrayList<ConnectionRecord>> kt
12799                            = s.connections.values().iterator();
12800                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12801                        ArrayList<ConnectionRecord> clist = kt.next();
12802                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12803                            // XXX should compute this based on the max of
12804                            // all connected clients.
12805                            ConnectionRecord cr = clist.get(i);
12806                            if (cr.binding.client == app) {
12807                                // Binding to ourself is not interesting.
12808                                continue;
12809                            }
12810                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12811                                ProcessRecord client = cr.binding.client;
12812                                int clientAdj = adj;
12813                                int myHiddenAdj = hiddenAdj;
12814                                if (myHiddenAdj > client.hiddenAdj) {
12815                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12816                                        myHiddenAdj = client.hiddenAdj;
12817                                    } else {
12818                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12819                                    }
12820                                }
12821                                int myClientHiddenAdj = clientHiddenAdj;
12822                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12823                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12824                                        myClientHiddenAdj = client.clientHiddenAdj;
12825                                    } else {
12826                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12827                                    }
12828                                }
12829                                int myEmptyAdj = emptyAdj;
12830                                if (myEmptyAdj > client.emptyAdj) {
12831                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12832                                        myEmptyAdj = client.emptyAdj;
12833                                    } else {
12834                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12835                                    }
12836                                }
12837                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12838                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12839                                String adjType = null;
12840                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12841                                    // Not doing bind OOM management, so treat
12842                                    // this guy more like a started service.
12843                                    if (app.hasShownUi && app != mHomeProcess) {
12844                                        // If this process has shown some UI, let it immediately
12845                                        // go to the LRU list because it may be pretty heavy with
12846                                        // UI stuff.  We'll tag it with a label just to help
12847                                        // debug and understand what is going on.
12848                                        if (adj > clientAdj) {
12849                                            adjType = "bound-bg-ui-services";
12850                                        }
12851                                        app.hidden = false;
12852                                        clientAdj = adj;
12853                                    } else {
12854                                        if (now >= (s.lastActivity
12855                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12856                                            // This service has not seen activity within
12857                                            // recent memory, so allow it to drop to the
12858                                            // LRU list if there is no other reason to keep
12859                                            // it around.  We'll also tag it with a label just
12860                                            // to help debug and undertand what is going on.
12861                                            if (adj > clientAdj) {
12862                                                adjType = "bound-bg-services";
12863                                            }
12864                                            clientAdj = adj;
12865                                        }
12866                                    }
12867                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12868                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12869                                        // If this connection is keeping the service
12870                                        // created, then we want to try to better follow
12871                                        // its memory management semantics for activities.
12872                                        // That is, if it is sitting in the background
12873                                        // LRU list as a hidden process (with activities),
12874                                        // we don't want the service it is connected to
12875                                        // to go into the empty LRU and quickly get killed,
12876                                        // because I'll we'll do is just end up restarting
12877                                        // the service.
12878                                        app.hasClientActivities |= client.hasActivities;
12879                                    }
12880                                }
12881                                if (adj > clientAdj) {
12882                                    // If this process has recently shown UI, and
12883                                    // the process that is binding to it is less
12884                                    // important than being visible, then we don't
12885                                    // care about the binding as much as we care
12886                                    // about letting this process get into the LRU
12887                                    // list to be killed and restarted if needed for
12888                                    // memory.
12889                                    if (app.hasShownUi && app != mHomeProcess
12890                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12891                                        adjType = "bound-bg-ui-services";
12892                                    } else {
12893                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12894                                                |Context.BIND_IMPORTANT)) != 0) {
12895                                            adj = clientAdj;
12896                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12897                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12898                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12899                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12900                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12901                                            adj = clientAdj;
12902                                        } else {
12903                                            app.pendingUiClean = true;
12904                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12905                                                adj = ProcessList.VISIBLE_APP_ADJ;
12906                                            }
12907                                        }
12908                                        if (!client.hidden) {
12909                                            app.hidden = false;
12910                                        }
12911                                        if (client.keeping) {
12912                                            app.keeping = true;
12913                                        }
12914                                        adjType = "service";
12915                                    }
12916                                }
12917                                if (adjType != null) {
12918                                    app.adjType = adjType;
12919                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12920                                            .REASON_SERVICE_IN_USE;
12921                                    app.adjSource = cr.binding.client;
12922                                    app.adjSourceOom = clientAdj;
12923                                    app.adjTarget = s.name;
12924                                }
12925                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12926                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12927                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12928                                    }
12929                                }
12930                            }
12931                            final ActivityRecord a = cr.activity;
12932                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12933                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12934                                        (a.visible || a.state == ActivityState.RESUMED
12935                                         || a.state == ActivityState.PAUSING)) {
12936                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12937                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12938                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12939                                    }
12940                                    app.hidden = false;
12941                                    app.adjType = "service";
12942                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12943                                            .REASON_SERVICE_IN_USE;
12944                                    app.adjSource = a;
12945                                    app.adjSourceOom = adj;
12946                                    app.adjTarget = s.name;
12947                                }
12948                            }
12949                        }
12950                    }
12951                }
12952            }
12953
12954            // Finally, if this process has active services running in it, we
12955            // would like to avoid killing it unless it would prevent the current
12956            // application from running.  By default we put the process in
12957            // with the rest of the background processes; as we scan through
12958            // its services we may bump it up from there.
12959            if (adj > hiddenAdj) {
12960                adj = hiddenAdj;
12961                app.hidden = false;
12962                app.adjType = "bg-services";
12963            }
12964        }
12965
12966        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12967                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12968            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12969            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12970                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12971                ContentProviderRecord cpr = jt.next();
12972                for (int i = cpr.connections.size()-1;
12973                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12974                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12975                        i--) {
12976                    ContentProviderConnection conn = cpr.connections.get(i);
12977                    ProcessRecord client = conn.client;
12978                    if (client == app) {
12979                        // Being our own client is not interesting.
12980                        continue;
12981                    }
12982                    int myHiddenAdj = hiddenAdj;
12983                    if (myHiddenAdj > client.hiddenAdj) {
12984                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12985                            myHiddenAdj = client.hiddenAdj;
12986                        } else {
12987                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12988                        }
12989                    }
12990                    int myClientHiddenAdj = clientHiddenAdj;
12991                    if (myClientHiddenAdj > client.clientHiddenAdj) {
12992                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
12993                            myClientHiddenAdj = client.clientHiddenAdj;
12994                        } else {
12995                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12996                        }
12997                    }
12998                    int myEmptyAdj = emptyAdj;
12999                    if (myEmptyAdj > client.emptyAdj) {
13000                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13001                            myEmptyAdj = client.emptyAdj;
13002                        } else {
13003                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13004                        }
13005                    }
13006                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13007                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13008                    if (adj > clientAdj) {
13009                        if (app.hasShownUi && app != mHomeProcess
13010                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13011                            app.adjType = "bg-ui-provider";
13012                        } else {
13013                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13014                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13015                            app.adjType = "provider";
13016                        }
13017                        if (!client.hidden) {
13018                            app.hidden = false;
13019                        }
13020                        if (client.keeping) {
13021                            app.keeping = true;
13022                        }
13023                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13024                                .REASON_PROVIDER_IN_USE;
13025                        app.adjSource = client;
13026                        app.adjSourceOom = clientAdj;
13027                        app.adjTarget = cpr.name;
13028                    }
13029                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13030                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13031                    }
13032                }
13033                // If the provider has external (non-framework) process
13034                // dependencies, ensure that its adjustment is at least
13035                // FOREGROUND_APP_ADJ.
13036                if (cpr.hasExternalProcessHandles()) {
13037                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13038                        adj = ProcessList.FOREGROUND_APP_ADJ;
13039                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13040                        app.hidden = false;
13041                        app.keeping = true;
13042                        app.adjType = "provider";
13043                        app.adjTarget = cpr.name;
13044                    }
13045                }
13046            }
13047        }
13048
13049        if (adj == ProcessList.SERVICE_ADJ) {
13050            if (doingAll) {
13051                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13052                mNewNumServiceProcs++;
13053            }
13054            if (app.serviceb) {
13055                adj = ProcessList.SERVICE_B_ADJ;
13056            }
13057        } else {
13058            app.serviceb = false;
13059        }
13060
13061        app.nonStoppingAdj = adj;
13062
13063        if (hasStoppingActivities) {
13064            // Only upgrade adjustment.
13065            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13066                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13067                app.adjType = "stopping";
13068            }
13069        }
13070
13071        app.curRawAdj = adj;
13072
13073        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13074        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13075        if (adj > app.maxAdj) {
13076            adj = app.maxAdj;
13077            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13078                schedGroup = Process.THREAD_GROUP_DEFAULT;
13079            }
13080        }
13081        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13082            app.keeping = true;
13083        }
13084
13085        if (app.hasAboveClient) {
13086            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13087            // then we need to drop its adjustment to be lower than the service's
13088            // in order to honor the request.  We want to drop it by one adjustment
13089            // level...  but there is special meaning applied to various levels so
13090            // we will skip some of them.
13091            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13092                // System process will not get dropped, ever
13093            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13094                adj = ProcessList.VISIBLE_APP_ADJ;
13095            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13096                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13097            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13098                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13099            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13100                adj++;
13101            }
13102        }
13103
13104        int importance = app.memImportance;
13105        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13106            app.curAdj = adj;
13107            app.curSchedGroup = schedGroup;
13108            if (!interesting) {
13109                // For this reporting, if there is not something explicitly
13110                // interesting in this process then we will push it to the
13111                // background importance.
13112                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13113            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13114                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13115            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13116                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13117            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13118                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13119            } else if (adj >= ProcessList.SERVICE_ADJ) {
13120                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13121            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13122                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13123            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13124                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13125            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13126                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13127            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13128                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13129            } else {
13130                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13131            }
13132        }
13133
13134        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13135        if (foregroundActivities != app.foregroundActivities) {
13136            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13137        }
13138        if (changes != 0) {
13139            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13140            app.memImportance = importance;
13141            app.foregroundActivities = foregroundActivities;
13142            int i = mPendingProcessChanges.size()-1;
13143            ProcessChangeItem item = null;
13144            while (i >= 0) {
13145                item = mPendingProcessChanges.get(i);
13146                if (item.pid == app.pid) {
13147                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13148                    break;
13149                }
13150                i--;
13151            }
13152            if (i < 0) {
13153                // No existing item in pending changes; need a new one.
13154                final int NA = mAvailProcessChanges.size();
13155                if (NA > 0) {
13156                    item = mAvailProcessChanges.remove(NA-1);
13157                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13158                } else {
13159                    item = new ProcessChangeItem();
13160                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13161                }
13162                item.changes = 0;
13163                item.pid = app.pid;
13164                item.uid = app.info.uid;
13165                if (mPendingProcessChanges.size() == 0) {
13166                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13167                            "*** Enqueueing dispatch processes changed!");
13168                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13169                }
13170                mPendingProcessChanges.add(item);
13171            }
13172            item.changes |= changes;
13173            item.importance = importance;
13174            item.foregroundActivities = foregroundActivities;
13175            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13176                    + Integer.toHexString(System.identityHashCode(item))
13177                    + " " + app.toShortString() + ": changes=" + item.changes
13178                    + " importance=" + item.importance
13179                    + " foreground=" + item.foregroundActivities
13180                    + " type=" + app.adjType + " source=" + app.adjSource
13181                    + " target=" + app.adjTarget);
13182        }
13183
13184        return app.curRawAdj;
13185    }
13186
13187    /**
13188     * Ask a given process to GC right now.
13189     */
13190    final void performAppGcLocked(ProcessRecord app) {
13191        try {
13192            app.lastRequestedGc = SystemClock.uptimeMillis();
13193            if (app.thread != null) {
13194                if (app.reportLowMemory) {
13195                    app.reportLowMemory = false;
13196                    app.thread.scheduleLowMemory();
13197                } else {
13198                    app.thread.processInBackground();
13199                }
13200            }
13201        } catch (Exception e) {
13202            // whatever.
13203        }
13204    }
13205
13206    /**
13207     * Returns true if things are idle enough to perform GCs.
13208     */
13209    private final boolean canGcNowLocked() {
13210        boolean processingBroadcasts = false;
13211        for (BroadcastQueue q : mBroadcastQueues) {
13212            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13213                processingBroadcasts = true;
13214            }
13215        }
13216        return !processingBroadcasts
13217                && (mSleeping || (mMainStack.mResumedActivity != null &&
13218                        mMainStack.mResumedActivity.idle));
13219    }
13220
13221    /**
13222     * Perform GCs on all processes that are waiting for it, but only
13223     * if things are idle.
13224     */
13225    final void performAppGcsLocked() {
13226        final int N = mProcessesToGc.size();
13227        if (N <= 0) {
13228            return;
13229        }
13230        if (canGcNowLocked()) {
13231            while (mProcessesToGc.size() > 0) {
13232                ProcessRecord proc = mProcessesToGc.remove(0);
13233                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13234                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13235                            <= SystemClock.uptimeMillis()) {
13236                        // To avoid spamming the system, we will GC processes one
13237                        // at a time, waiting a few seconds between each.
13238                        performAppGcLocked(proc);
13239                        scheduleAppGcsLocked();
13240                        return;
13241                    } else {
13242                        // It hasn't been long enough since we last GCed this
13243                        // process...  put it in the list to wait for its time.
13244                        addProcessToGcListLocked(proc);
13245                        break;
13246                    }
13247                }
13248            }
13249
13250            scheduleAppGcsLocked();
13251        }
13252    }
13253
13254    /**
13255     * If all looks good, perform GCs on all processes waiting for them.
13256     */
13257    final void performAppGcsIfAppropriateLocked() {
13258        if (canGcNowLocked()) {
13259            performAppGcsLocked();
13260            return;
13261        }
13262        // Still not idle, wait some more.
13263        scheduleAppGcsLocked();
13264    }
13265
13266    /**
13267     * Schedule the execution of all pending app GCs.
13268     */
13269    final void scheduleAppGcsLocked() {
13270        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13271
13272        if (mProcessesToGc.size() > 0) {
13273            // Schedule a GC for the time to the next process.
13274            ProcessRecord proc = mProcessesToGc.get(0);
13275            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13276
13277            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13278            long now = SystemClock.uptimeMillis();
13279            if (when < (now+GC_TIMEOUT)) {
13280                when = now + GC_TIMEOUT;
13281            }
13282            mHandler.sendMessageAtTime(msg, when);
13283        }
13284    }
13285
13286    /**
13287     * Add a process to the array of processes waiting to be GCed.  Keeps the
13288     * list in sorted order by the last GC time.  The process can't already be
13289     * on the list.
13290     */
13291    final void addProcessToGcListLocked(ProcessRecord proc) {
13292        boolean added = false;
13293        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13294            if (mProcessesToGc.get(i).lastRequestedGc <
13295                    proc.lastRequestedGc) {
13296                added = true;
13297                mProcessesToGc.add(i+1, proc);
13298                break;
13299            }
13300        }
13301        if (!added) {
13302            mProcessesToGc.add(0, proc);
13303        }
13304    }
13305
13306    /**
13307     * Set up to ask a process to GC itself.  This will either do it
13308     * immediately, or put it on the list of processes to gc the next
13309     * time things are idle.
13310     */
13311    final void scheduleAppGcLocked(ProcessRecord app) {
13312        long now = SystemClock.uptimeMillis();
13313        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13314            return;
13315        }
13316        if (!mProcessesToGc.contains(app)) {
13317            addProcessToGcListLocked(app);
13318            scheduleAppGcsLocked();
13319        }
13320    }
13321
13322    final void checkExcessivePowerUsageLocked(boolean doKills) {
13323        updateCpuStatsNow();
13324
13325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13326        boolean doWakeKills = doKills;
13327        boolean doCpuKills = doKills;
13328        if (mLastPowerCheckRealtime == 0) {
13329            doWakeKills = false;
13330        }
13331        if (mLastPowerCheckUptime == 0) {
13332            doCpuKills = false;
13333        }
13334        if (stats.isScreenOn()) {
13335            doWakeKills = false;
13336        }
13337        final long curRealtime = SystemClock.elapsedRealtime();
13338        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13339        final long curUptime = SystemClock.uptimeMillis();
13340        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13341        mLastPowerCheckRealtime = curRealtime;
13342        mLastPowerCheckUptime = curUptime;
13343        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13344            doWakeKills = false;
13345        }
13346        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13347            doCpuKills = false;
13348        }
13349        int i = mLruProcesses.size();
13350        while (i > 0) {
13351            i--;
13352            ProcessRecord app = mLruProcesses.get(i);
13353            if (!app.keeping) {
13354                long wtime;
13355                synchronized (stats) {
13356                    wtime = stats.getProcessWakeTime(app.info.uid,
13357                            app.pid, curRealtime);
13358                }
13359                long wtimeUsed = wtime - app.lastWakeTime;
13360                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13361                if (DEBUG_POWER) {
13362                    StringBuilder sb = new StringBuilder(128);
13363                    sb.append("Wake for ");
13364                    app.toShortString(sb);
13365                    sb.append(": over ");
13366                    TimeUtils.formatDuration(realtimeSince, sb);
13367                    sb.append(" used ");
13368                    TimeUtils.formatDuration(wtimeUsed, sb);
13369                    sb.append(" (");
13370                    sb.append((wtimeUsed*100)/realtimeSince);
13371                    sb.append("%)");
13372                    Slog.i(TAG, sb.toString());
13373                    sb.setLength(0);
13374                    sb.append("CPU for ");
13375                    app.toShortString(sb);
13376                    sb.append(": over ");
13377                    TimeUtils.formatDuration(uptimeSince, sb);
13378                    sb.append(" used ");
13379                    TimeUtils.formatDuration(cputimeUsed, sb);
13380                    sb.append(" (");
13381                    sb.append((cputimeUsed*100)/uptimeSince);
13382                    sb.append("%)");
13383                    Slog.i(TAG, sb.toString());
13384                }
13385                // If a process has held a wake lock for more
13386                // than 50% of the time during this period,
13387                // that sounds bad.  Kill!
13388                if (doWakeKills && realtimeSince > 0
13389                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13390                    synchronized (stats) {
13391                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13392                                realtimeSince, wtimeUsed);
13393                    }
13394                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13395                            + " (pid " + app.pid + "): held " + wtimeUsed
13396                            + " during " + realtimeSince);
13397                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13398                            app.processName, app.setAdj, "excessive wake lock");
13399                    Process.killProcessQuiet(app.pid);
13400                } else if (doCpuKills && uptimeSince > 0
13401                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13402                    synchronized (stats) {
13403                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13404                                uptimeSince, cputimeUsed);
13405                    }
13406                    Slog.w(TAG, "Excessive CPU in " + app.processName
13407                            + " (pid " + app.pid + "): used " + cputimeUsed
13408                            + " during " + uptimeSince);
13409                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13410                            app.processName, app.setAdj, "excessive cpu");
13411                    Process.killProcessQuiet(app.pid);
13412                } else {
13413                    app.lastWakeTime = wtime;
13414                    app.lastCpuTime = app.curCpuTime;
13415                }
13416            }
13417        }
13418    }
13419
13420    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13421            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13422        app.hiddenAdj = hiddenAdj;
13423        app.clientHiddenAdj = clientHiddenAdj;
13424        app.emptyAdj = emptyAdj;
13425
13426        if (app.thread == null) {
13427            return false;
13428        }
13429
13430        final boolean wasKeeping = app.keeping;
13431
13432        boolean success = true;
13433
13434        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13435
13436        if (app.curRawAdj != app.setRawAdj) {
13437            if (wasKeeping && !app.keeping) {
13438                // This app is no longer something we want to keep.  Note
13439                // its current wake lock time to later know to kill it if
13440                // it is not behaving well.
13441                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13442                synchronized (stats) {
13443                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13444                            app.pid, SystemClock.elapsedRealtime());
13445                }
13446                app.lastCpuTime = app.curCpuTime;
13447            }
13448
13449            app.setRawAdj = app.curRawAdj;
13450        }
13451
13452        if (app.curAdj != app.setAdj) {
13453            if (Process.setOomAdj(app.pid, app.curAdj)) {
13454                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13455                    TAG, "Set " + app.pid + " " + app.processName +
13456                    " adj " + app.curAdj + ": " + app.adjType);
13457                app.setAdj = app.curAdj;
13458            } else {
13459                success = false;
13460                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13461            }
13462        }
13463        if (app.setSchedGroup != app.curSchedGroup) {
13464            app.setSchedGroup = app.curSchedGroup;
13465            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13466                    "Setting process group of " + app.processName
13467                    + " to " + app.curSchedGroup);
13468            if (app.waitingToKill != null &&
13469                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13470                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13471                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13472                        app.processName, app.setAdj, app.waitingToKill);
13473                app.killedBackground = true;
13474                Process.killProcessQuiet(app.pid);
13475                success = false;
13476            } else {
13477                if (true) {
13478                    long oldId = Binder.clearCallingIdentity();
13479                    try {
13480                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13481                    } catch (Exception e) {
13482                        Slog.w(TAG, "Failed setting process group of " + app.pid
13483                                + " to " + app.curSchedGroup);
13484                        e.printStackTrace();
13485                    } finally {
13486                        Binder.restoreCallingIdentity(oldId);
13487                    }
13488                } else {
13489                    if (app.thread != null) {
13490                        try {
13491                            app.thread.setSchedulingGroup(app.curSchedGroup);
13492                        } catch (RemoteException e) {
13493                        }
13494                    }
13495                }
13496            }
13497        }
13498        return success;
13499    }
13500
13501    private final ActivityRecord resumedAppLocked() {
13502        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13503        if (resumedActivity == null || resumedActivity.app == null) {
13504            resumedActivity = mMainStack.mPausingActivity;
13505            if (resumedActivity == null || resumedActivity.app == null) {
13506                resumedActivity = mMainStack.topRunningActivityLocked(null);
13507            }
13508        }
13509        return resumedActivity;
13510    }
13511
13512    final boolean updateOomAdjLocked(ProcessRecord app) {
13513        final ActivityRecord TOP_ACT = resumedAppLocked();
13514        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13515        int curAdj = app.curAdj;
13516        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13517            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13518
13519        mAdjSeq++;
13520
13521        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13522                app.emptyAdj, TOP_APP, false);
13523        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13524            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13525        if (nowHidden != wasHidden) {
13526            // Changed to/from hidden state, so apps after it in the LRU
13527            // list may also be changed.
13528            updateOomAdjLocked();
13529        }
13530        return success;
13531    }
13532
13533    final void updateOomAdjLocked() {
13534        final ActivityRecord TOP_ACT = resumedAppLocked();
13535        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13536        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13537
13538        if (false) {
13539            RuntimeException e = new RuntimeException();
13540            e.fillInStackTrace();
13541            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13542        }
13543
13544        mAdjSeq++;
13545        mNewNumServiceProcs = 0;
13546
13547        final int emptyProcessLimit;
13548        final int hiddenProcessLimit;
13549        if (mProcessLimit <= 0) {
13550            emptyProcessLimit = hiddenProcessLimit = 0;
13551        } else if (mProcessLimit == 1) {
13552            emptyProcessLimit = 1;
13553            hiddenProcessLimit = 0;
13554        } else {
13555            emptyProcessLimit = (mProcessLimit*2)/3;
13556            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13557        }
13558
13559        // Let's determine how many processes we have running vs.
13560        // how many slots we have for background processes; we may want
13561        // to put multiple processes in a slot of there are enough of
13562        // them.
13563        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13564                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13565        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13566        if (numEmptyProcs > hiddenProcessLimit) {
13567            // If there are more empty processes than our limit on hidden
13568            // processes, then use the hidden process limit for the factor.
13569            // This ensures that the really old empty processes get pushed
13570            // down to the bottom, so if we are running low on memory we will
13571            // have a better chance at keeping around more hidden processes
13572            // instead of a gazillion empty processes.
13573            numEmptyProcs = hiddenProcessLimit;
13574        }
13575        int emptyFactor = numEmptyProcs/numSlots;
13576        if (emptyFactor < 1) emptyFactor = 1;
13577        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13578        if (hiddenFactor < 1) hiddenFactor = 1;
13579        int stepHidden = 0;
13580        int stepEmpty = 0;
13581        int numHidden = 0;
13582        int numEmpty = 0;
13583        int numTrimming = 0;
13584
13585        mNumNonHiddenProcs = 0;
13586        mNumHiddenProcs = 0;
13587
13588        // First update the OOM adjustment for each of the
13589        // application processes based on their current state.
13590        int i = mLruProcesses.size();
13591        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13592        int nextHiddenAdj = curHiddenAdj+1;
13593        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13594        int nextEmptyAdj = curEmptyAdj+2;
13595        int curClientHiddenAdj = curEmptyAdj;
13596        while (i > 0) {
13597            i--;
13598            ProcessRecord app = mLruProcesses.get(i);
13599            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13600            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13601            if (!app.killedBackground) {
13602                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13603                    // This process was assigned as a hidden process...  step the
13604                    // hidden level.
13605                    mNumHiddenProcs++;
13606                    if (curHiddenAdj != nextHiddenAdj) {
13607                        stepHidden++;
13608                        if (stepHidden >= hiddenFactor) {
13609                            stepHidden = 0;
13610                            curHiddenAdj = nextHiddenAdj;
13611                            nextHiddenAdj += 2;
13612                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13613                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13614                            }
13615                            if (curClientHiddenAdj <= curHiddenAdj) {
13616                                curClientHiddenAdj = curHiddenAdj + 1;
13617                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13618                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13619                                }
13620                            }
13621                        }
13622                    }
13623                    numHidden++;
13624                    if (numHidden > hiddenProcessLimit) {
13625                        Slog.i(TAG, "No longer want " + app.processName
13626                                + " (pid " + app.pid + "): hidden #" + numHidden);
13627                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13628                                app.processName, app.setAdj, "too many background");
13629                        app.killedBackground = true;
13630                        Process.killProcessQuiet(app.pid);
13631                    }
13632                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13633                    // This process has a client that has activities.  We will have
13634                    // given it the current hidden adj; here we will just leave it
13635                    // without stepping the hidden adj.
13636                    curClientHiddenAdj++;
13637                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13638                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13639                    }
13640                } else {
13641                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13642                        // This process was assigned as an empty process...  step the
13643                        // empty level.
13644                        if (curEmptyAdj != nextEmptyAdj) {
13645                            stepEmpty++;
13646                            if (stepEmpty >= emptyFactor) {
13647                                stepEmpty = 0;
13648                                curEmptyAdj = nextEmptyAdj;
13649                                nextEmptyAdj += 2;
13650                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13651                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13652                                }
13653                            }
13654                        }
13655                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13656                        mNumNonHiddenProcs++;
13657                    }
13658                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13659                            && !app.hasClientActivities) {
13660                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13661                                && app.lastActivityTime < oldTime) {
13662                            Slog.i(TAG, "No longer want " + app.processName
13663                                    + " (pid " + app.pid + "): empty for "
13664                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13665                                            / 1000) + "s");
13666                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13667                                    app.processName, app.setAdj, "old background process");
13668                            app.killedBackground = true;
13669                            Process.killProcessQuiet(app.pid);
13670                        } else {
13671                            numEmpty++;
13672                            if (numEmpty > emptyProcessLimit) {
13673                                Slog.i(TAG, "No longer want " + app.processName
13674                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13675                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13676                                        app.processName, app.setAdj, "too many background");
13677                                app.killedBackground = true;
13678                                Process.killProcessQuiet(app.pid);
13679                            }
13680                        }
13681                    }
13682                }
13683                if (app.isolated && app.services.size() <= 0) {
13684                    // If this is an isolated process, and there are no
13685                    // services running in it, then the process is no longer
13686                    // needed.  We agressively kill these because we can by
13687                    // definition not re-use the same process again, and it is
13688                    // good to avoid having whatever code was running in them
13689                    // left sitting around after no longer needed.
13690                    Slog.i(TAG, "Isolated process " + app.processName
13691                            + " (pid " + app.pid + ") no longer needed");
13692                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13693                            app.processName, app.setAdj, "isolated not needed");
13694                    app.killedBackground = true;
13695                    Process.killProcessQuiet(app.pid);
13696                }
13697                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13698                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13699                        && !app.killedBackground) {
13700                    numTrimming++;
13701                }
13702            }
13703        }
13704
13705        mNumServiceProcs = mNewNumServiceProcs;
13706
13707        // Now determine the memory trimming level of background processes.
13708        // Unfortunately we need to start at the back of the list to do this
13709        // properly.  We only do this if the number of background apps we
13710        // are managing to keep around is less than half the maximum we desire;
13711        // if we are keeping a good number around, we'll let them use whatever
13712        // memory they want.
13713        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13714                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13715            final int numHiddenAndEmpty = numHidden + numEmpty;
13716            final int N = mLruProcesses.size();
13717            int factor = numTrimming/3;
13718            int minFactor = 2;
13719            if (mHomeProcess != null) minFactor++;
13720            if (mPreviousProcess != null) minFactor++;
13721            if (factor < minFactor) factor = minFactor;
13722            int step = 0;
13723            int fgTrimLevel;
13724            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13725                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13726            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13727                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13728            } else {
13729                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13730            }
13731            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13732            for (i=0; i<N; i++) {
13733                ProcessRecord app = mLruProcesses.get(i);
13734                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13735                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13736                        && !app.killedBackground) {
13737                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13738                        try {
13739                            app.thread.scheduleTrimMemory(curLevel);
13740                        } catch (RemoteException e) {
13741                        }
13742                        if (false) {
13743                            // For now we won't do this; our memory trimming seems
13744                            // to be good enough at this point that destroying
13745                            // activities causes more harm than good.
13746                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13747                                    && app != mHomeProcess && app != mPreviousProcess) {
13748                                // Need to do this on its own message because the stack may not
13749                                // be in a consistent state at this point.
13750                                // For these apps we will also finish their activities
13751                                // to help them free memory.
13752                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13753                            }
13754                        }
13755                    }
13756                    app.trimMemoryLevel = curLevel;
13757                    step++;
13758                    if (step >= factor) {
13759                        step = 0;
13760                        switch (curLevel) {
13761                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13762                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13763                                break;
13764                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13765                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13766                                break;
13767                        }
13768                    }
13769                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13770                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13771                            && app.thread != null) {
13772                        try {
13773                            app.thread.scheduleTrimMemory(
13774                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13775                        } catch (RemoteException e) {
13776                        }
13777                    }
13778                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13779                } else {
13780                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13781                            && app.pendingUiClean) {
13782                        // If this application is now in the background and it
13783                        // had done UI, then give it the special trim level to
13784                        // have it free UI resources.
13785                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13786                        if (app.trimMemoryLevel < level && app.thread != null) {
13787                            try {
13788                                app.thread.scheduleTrimMemory(level);
13789                            } catch (RemoteException e) {
13790                            }
13791                        }
13792                        app.pendingUiClean = false;
13793                    }
13794                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13795                        try {
13796                            app.thread.scheduleTrimMemory(fgTrimLevel);
13797                        } catch (RemoteException e) {
13798                        }
13799                    }
13800                    app.trimMemoryLevel = fgTrimLevel;
13801                }
13802            }
13803        } else {
13804            final int N = mLruProcesses.size();
13805            for (i=0; i<N; i++) {
13806                ProcessRecord app = mLruProcesses.get(i);
13807                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13808                        && app.pendingUiClean) {
13809                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13810                            && app.thread != null) {
13811                        try {
13812                            app.thread.scheduleTrimMemory(
13813                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13814                        } catch (RemoteException e) {
13815                        }
13816                    }
13817                    app.pendingUiClean = false;
13818                }
13819                app.trimMemoryLevel = 0;
13820            }
13821        }
13822
13823        if (mAlwaysFinishActivities) {
13824            // Need to do this on its own message because the stack may not
13825            // be in a consistent state at this point.
13826            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13827        }
13828    }
13829
13830    final void trimApplications() {
13831        synchronized (this) {
13832            int i;
13833
13834            // First remove any unused application processes whose package
13835            // has been removed.
13836            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13837                final ProcessRecord app = mRemovedProcesses.get(i);
13838                if (app.activities.size() == 0
13839                        && app.curReceiver == null && app.services.size() == 0) {
13840                    Slog.i(
13841                        TAG, "Exiting empty application process "
13842                        + app.processName + " ("
13843                        + (app.thread != null ? app.thread.asBinder() : null)
13844                        + ")\n");
13845                    if (app.pid > 0 && app.pid != MY_PID) {
13846                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13847                                app.processName, app.setAdj, "empty");
13848                        Process.killProcessQuiet(app.pid);
13849                    } else {
13850                        try {
13851                            app.thread.scheduleExit();
13852                        } catch (Exception e) {
13853                            // Ignore exceptions.
13854                        }
13855                    }
13856                    cleanUpApplicationRecordLocked(app, false, true, -1);
13857                    mRemovedProcesses.remove(i);
13858
13859                    if (app.persistent) {
13860                        if (app.persistent) {
13861                            addAppLocked(app.info, false);
13862                        }
13863                    }
13864                }
13865            }
13866
13867            // Now update the oom adj for all processes.
13868            updateOomAdjLocked();
13869        }
13870    }
13871
13872    /** This method sends the specified signal to each of the persistent apps */
13873    public void signalPersistentProcesses(int sig) throws RemoteException {
13874        if (sig != Process.SIGNAL_USR1) {
13875            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13876        }
13877
13878        synchronized (this) {
13879            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13880                    != PackageManager.PERMISSION_GRANTED) {
13881                throw new SecurityException("Requires permission "
13882                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13883            }
13884
13885            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13886                ProcessRecord r = mLruProcesses.get(i);
13887                if (r.thread != null && r.persistent) {
13888                    Process.sendSignal(r.pid, sig);
13889                }
13890            }
13891        }
13892    }
13893
13894    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13895        if (proc == null || proc == mProfileProc) {
13896            proc = mProfileProc;
13897            path = mProfileFile;
13898            profileType = mProfileType;
13899            clearProfilerLocked();
13900        }
13901        if (proc == null) {
13902            return;
13903        }
13904        try {
13905            proc.thread.profilerControl(false, path, null, profileType);
13906        } catch (RemoteException e) {
13907            throw new IllegalStateException("Process disappeared");
13908        }
13909    }
13910
13911    private void clearProfilerLocked() {
13912        if (mProfileFd != null) {
13913            try {
13914                mProfileFd.close();
13915            } catch (IOException e) {
13916            }
13917        }
13918        mProfileApp = null;
13919        mProfileProc = null;
13920        mProfileFile = null;
13921        mProfileType = 0;
13922        mAutoStopProfiler = false;
13923    }
13924
13925    public boolean profileControl(String process, int userId, boolean start,
13926            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13927
13928        try {
13929            synchronized (this) {
13930                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13931                // its own permission.
13932                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13933                        != PackageManager.PERMISSION_GRANTED) {
13934                    throw new SecurityException("Requires permission "
13935                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13936                }
13937
13938                if (start && fd == null) {
13939                    throw new IllegalArgumentException("null fd");
13940                }
13941
13942                ProcessRecord proc = null;
13943                if (process != null) {
13944                    proc = findProcessLocked(process, userId, "profileControl");
13945                }
13946
13947                if (start && (proc == null || proc.thread == null)) {
13948                    throw new IllegalArgumentException("Unknown process: " + process);
13949                }
13950
13951                if (start) {
13952                    stopProfilerLocked(null, null, 0);
13953                    setProfileApp(proc.info, proc.processName, path, fd, false);
13954                    mProfileProc = proc;
13955                    mProfileType = profileType;
13956                    try {
13957                        fd = fd.dup();
13958                    } catch (IOException e) {
13959                        fd = null;
13960                    }
13961                    proc.thread.profilerControl(start, path, fd, profileType);
13962                    fd = null;
13963                    mProfileFd = null;
13964                } else {
13965                    stopProfilerLocked(proc, path, profileType);
13966                    if (fd != null) {
13967                        try {
13968                            fd.close();
13969                        } catch (IOException e) {
13970                        }
13971                    }
13972                }
13973
13974                return true;
13975            }
13976        } catch (RemoteException e) {
13977            throw new IllegalStateException("Process disappeared");
13978        } finally {
13979            if (fd != null) {
13980                try {
13981                    fd.close();
13982                } catch (IOException e) {
13983                }
13984            }
13985        }
13986    }
13987
13988    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13989        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13990                userId, true, true, callName, null);
13991        ProcessRecord proc = null;
13992        try {
13993            int pid = Integer.parseInt(process);
13994            synchronized (mPidsSelfLocked) {
13995                proc = mPidsSelfLocked.get(pid);
13996            }
13997        } catch (NumberFormatException e) {
13998        }
13999
14000        if (proc == null) {
14001            HashMap<String, SparseArray<ProcessRecord>> all
14002                    = mProcessNames.getMap();
14003            SparseArray<ProcessRecord> procs = all.get(process);
14004            if (procs != null && procs.size() > 0) {
14005                proc = procs.valueAt(0);
14006                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14007                    for (int i=1; i<procs.size(); i++) {
14008                        ProcessRecord thisProc = procs.valueAt(i);
14009                        if (thisProc.userId == userId) {
14010                            proc = thisProc;
14011                            break;
14012                        }
14013                    }
14014                }
14015            }
14016        }
14017
14018        return proc;
14019    }
14020
14021    public boolean dumpHeap(String process, int userId, boolean managed,
14022            String path, ParcelFileDescriptor fd) throws RemoteException {
14023
14024        try {
14025            synchronized (this) {
14026                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14027                // its own permission (same as profileControl).
14028                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14029                        != PackageManager.PERMISSION_GRANTED) {
14030                    throw new SecurityException("Requires permission "
14031                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14032                }
14033
14034                if (fd == null) {
14035                    throw new IllegalArgumentException("null fd");
14036                }
14037
14038                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14039                if (proc == null || proc.thread == null) {
14040                    throw new IllegalArgumentException("Unknown process: " + process);
14041                }
14042
14043                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14044                if (!isDebuggable) {
14045                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14046                        throw new SecurityException("Process not debuggable: " + proc);
14047                    }
14048                }
14049
14050                proc.thread.dumpHeap(managed, path, fd);
14051                fd = null;
14052                return true;
14053            }
14054        } catch (RemoteException e) {
14055            throw new IllegalStateException("Process disappeared");
14056        } finally {
14057            if (fd != null) {
14058                try {
14059                    fd.close();
14060                } catch (IOException e) {
14061                }
14062            }
14063        }
14064    }
14065
14066    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14067    public void monitor() {
14068        synchronized (this) { }
14069    }
14070
14071    void onCoreSettingsChange(Bundle settings) {
14072        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14073            ProcessRecord processRecord = mLruProcesses.get(i);
14074            try {
14075                if (processRecord.thread != null) {
14076                    processRecord.thread.setCoreSettings(settings);
14077                }
14078            } catch (RemoteException re) {
14079                /* ignore */
14080            }
14081        }
14082    }
14083
14084    // Multi-user methods
14085
14086    @Override
14087    public boolean switchUser(int userId) {
14088        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14089                != PackageManager.PERMISSION_GRANTED) {
14090            String msg = "Permission Denial: switchUser() from pid="
14091                    + Binder.getCallingPid()
14092                    + ", uid=" + Binder.getCallingUid()
14093                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14094            Slog.w(TAG, msg);
14095            throw new SecurityException(msg);
14096        }
14097
14098        final long ident = Binder.clearCallingIdentity();
14099        try {
14100            synchronized (this) {
14101                final int oldUserId = mCurrentUserId;
14102                if (oldUserId == userId) {
14103                    return true;
14104                }
14105
14106                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14107                if (userInfo == null) {
14108                    Slog.w(TAG, "No user info for user #" + userId);
14109                    return false;
14110                }
14111
14112                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14113                        R.anim.screen_user_enter);
14114
14115                // If the user we are switching to is not currently started, then
14116                // we need to start it now.
14117                if (mStartedUsers.get(userId) == null) {
14118                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14119                    updateStartedUserArrayLocked();
14120                }
14121
14122                mCurrentUserId = userId;
14123                mCurrentUserArray = new int[] { userId };
14124                final Integer userIdInt = Integer.valueOf(userId);
14125                mUserLru.remove(userIdInt);
14126                mUserLru.add(userIdInt);
14127
14128                mWindowManager.setCurrentUser(userId);
14129
14130                // Once the internal notion of the active user has switched, we lock the device
14131                // with the option to show the user switcher on the keyguard.
14132                mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
14133
14134                final UserStartedState uss = mStartedUsers.get(userId);
14135
14136                // Make sure user is in the started state.  If it is currently
14137                // stopping, we need to knock that off.
14138                if (uss.mState == UserStartedState.STATE_STOPPING) {
14139                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14140                    // so we can just fairly silently bring the user back from
14141                    // the almost-dead.
14142                    uss.mState = UserStartedState.STATE_RUNNING;
14143                    updateStartedUserArrayLocked();
14144                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14145                    // This means ACTION_SHUTDOWN has been sent, so we will
14146                    // need to treat this as a new boot of the user.
14147                    uss.mState = UserStartedState.STATE_BOOTING;
14148                    updateStartedUserArrayLocked();
14149                }
14150
14151                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14152                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14153                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14154                        oldUserId, userId, uss));
14155                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14156                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14157                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14158                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14159                        | Intent.FLAG_RECEIVER_FOREGROUND);
14160                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14161                broadcastIntentLocked(null, null, intent,
14162                        null, null, 0, null, null, null,
14163                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14164
14165                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14166                    if (userId != 0) {
14167                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14168                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14169                        broadcastIntentLocked(null, null, intent, null,
14170                                new IIntentReceiver.Stub() {
14171                                    public void performReceive(Intent intent, int resultCode,
14172                                            String data, Bundle extras, boolean ordered,
14173                                            boolean sticky, int sendingUser) {
14174                                        userInitialized(uss);
14175                                    }
14176                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14177                                userId);
14178                        uss.initializing = true;
14179                    } else {
14180                        getUserManagerLocked().makeInitialized(userInfo.id);
14181                    }
14182                }
14183
14184                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14185                if (!haveActivities) {
14186                    startHomeActivityLocked(userId);
14187                }
14188
14189                getUserManagerLocked().userForeground(userId);
14190                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14191            }
14192        } finally {
14193            Binder.restoreCallingIdentity(ident);
14194        }
14195
14196        return true;
14197    }
14198
14199    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14200        long ident = Binder.clearCallingIdentity();
14201        try {
14202            Intent intent;
14203            if (oldUserId >= 0) {
14204                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14205                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14206                        | Intent.FLAG_RECEIVER_FOREGROUND);
14207                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14208                broadcastIntentLocked(null, null, intent,
14209                        null, null, 0, null, null, null,
14210                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14211            }
14212            if (newUserId >= 0) {
14213                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14214                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14215                        | Intent.FLAG_RECEIVER_FOREGROUND);
14216                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14217                broadcastIntentLocked(null, null, intent,
14218                        null, null, 0, null, null, null,
14219                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14220                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14221                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14222                        | Intent.FLAG_RECEIVER_FOREGROUND);
14223                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14224                broadcastIntentLocked(null, null, intent,
14225                        null, null, 0, null, null,
14226                        android.Manifest.permission.MANAGE_USERS,
14227                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14228                intent = new Intent(Intent.ACTION_USER_STARTING);
14229                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14230                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14231                broadcastIntentLocked(null, null, intent,
14232                        null, new IIntentReceiver.Stub() {
14233                            @Override
14234                            public void performReceive(Intent intent, int resultCode, String data,
14235                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14236                                    throws RemoteException {
14237                            }
14238                        }, 0, null, null,
14239                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14240                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14241            }
14242        } finally {
14243            Binder.restoreCallingIdentity(ident);
14244        }
14245    }
14246
14247    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14248            final int newUserId) {
14249        final int N = mUserSwitchObservers.beginBroadcast();
14250        if (N > 0) {
14251            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14252                int mCount = 0;
14253                @Override
14254                public void sendResult(Bundle data) throws RemoteException {
14255                    synchronized (ActivityManagerService.this) {
14256                        if (mCurUserSwitchCallback == this) {
14257                            mCount++;
14258                            if (mCount == N) {
14259                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14260                            }
14261                        }
14262                    }
14263                }
14264            };
14265            synchronized (this) {
14266                uss.switching = true;
14267                mCurUserSwitchCallback = callback;
14268            }
14269            for (int i=0; i<N; i++) {
14270                try {
14271                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14272                            newUserId, callback);
14273                } catch (RemoteException e) {
14274                }
14275            }
14276        } else {
14277            synchronized (this) {
14278                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14279            }
14280        }
14281        mUserSwitchObservers.finishBroadcast();
14282    }
14283
14284    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14285        synchronized (this) {
14286            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14287            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14288        }
14289    }
14290
14291    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14292        mCurUserSwitchCallback = null;
14293        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14294        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14295                oldUserId, newUserId, uss));
14296    }
14297
14298    void userInitialized(UserStartedState uss) {
14299        synchronized (ActivityManagerService.this) {
14300            getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14301            uss.initializing = false;
14302            completeSwitchAndInitalizeLocked(uss);
14303        }
14304    }
14305
14306    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14307        final int N = mUserSwitchObservers.beginBroadcast();
14308        for (int i=0; i<N; i++) {
14309            try {
14310                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14311            } catch (RemoteException e) {
14312            }
14313        }
14314        mUserSwitchObservers.finishBroadcast();
14315        synchronized (this) {
14316            uss.switching = false;
14317            completeSwitchAndInitalizeLocked(uss);
14318        }
14319    }
14320
14321    void completeSwitchAndInitalizeLocked(UserStartedState uss) {
14322        if (!uss.switching && !uss.initializing) {
14323            mWindowManager.stopFreezingScreen();
14324        }
14325    }
14326
14327    void finishUserSwitch(UserStartedState uss) {
14328        synchronized (this) {
14329            if (uss.mState == UserStartedState.STATE_BOOTING
14330                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14331                uss.mState = UserStartedState.STATE_RUNNING;
14332                final int userId = uss.mHandle.getIdentifier();
14333                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14334                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14335                broadcastIntentLocked(null, null, intent,
14336                        null, null, 0, null, null,
14337                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14338                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14339            }
14340            int num = mUserLru.size();
14341            int i = 0;
14342            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14343                Integer oldUserId = mUserLru.get(i);
14344                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14345                if (oldUss == null) {
14346                    // Shouldn't happen, but be sane if it does.
14347                    mUserLru.remove(i);
14348                    num--;
14349                    continue;
14350                }
14351                if (oldUss.mState == UserStartedState.STATE_STOPPING
14352                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14353                    // This user is already stopping, doesn't count.
14354                    num--;
14355                    i++;
14356                    continue;
14357                }
14358                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14359                    // Owner and current can't be stopped, but count as running.
14360                    i++;
14361                    continue;
14362                }
14363                // This is a user to be stopped.
14364                stopUserLocked(oldUserId, null);
14365                num--;
14366                i++;
14367            }
14368        }
14369    }
14370
14371    @Override
14372    public int stopUser(final int userId, final IStopUserCallback callback) {
14373        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14374                != PackageManager.PERMISSION_GRANTED) {
14375            String msg = "Permission Denial: switchUser() from pid="
14376                    + Binder.getCallingPid()
14377                    + ", uid=" + Binder.getCallingUid()
14378                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14379            Slog.w(TAG, msg);
14380            throw new SecurityException(msg);
14381        }
14382        if (userId <= 0) {
14383            throw new IllegalArgumentException("Can't stop primary user " + userId);
14384        }
14385        synchronized (this) {
14386            return stopUserLocked(userId, callback);
14387        }
14388    }
14389
14390    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14391        if (mCurrentUserId == userId) {
14392            return ActivityManager.USER_OP_IS_CURRENT;
14393        }
14394
14395        final UserStartedState uss = mStartedUsers.get(userId);
14396        if (uss == null) {
14397            // User is not started, nothing to do...  but we do need to
14398            // callback if requested.
14399            if (callback != null) {
14400                mHandler.post(new Runnable() {
14401                    @Override
14402                    public void run() {
14403                        try {
14404                            callback.userStopped(userId);
14405                        } catch (RemoteException e) {
14406                        }
14407                    }
14408                });
14409            }
14410            return ActivityManager.USER_OP_SUCCESS;
14411        }
14412
14413        if (callback != null) {
14414            uss.mStopCallbacks.add(callback);
14415        }
14416
14417        if (uss.mState != UserStartedState.STATE_STOPPING
14418                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14419            uss.mState = UserStartedState.STATE_STOPPING;
14420            updateStartedUserArrayLocked();
14421
14422            long ident = Binder.clearCallingIdentity();
14423            try {
14424                // We are going to broadcast ACTION_USER_STOPPING and then
14425                // once that is down send a final ACTION_SHUTDOWN and then
14426                // stop the user.
14427                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14428                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14429                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14430                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14431                // This is the result receiver for the final shutdown broadcast.
14432                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14433                    @Override
14434                    public void performReceive(Intent intent, int resultCode, String data,
14435                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14436                        finishUserStop(uss);
14437                    }
14438                };
14439                // This is the result receiver for the initial stopping broadcast.
14440                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14441                    @Override
14442                    public void performReceive(Intent intent, int resultCode, String data,
14443                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14444                        // On to the next.
14445                        synchronized (ActivityManagerService.this) {
14446                            if (uss.mState != UserStartedState.STATE_STOPPING) {
14447                                // Whoops, we are being started back up.  Abort, abort!
14448                                return;
14449                            }
14450                            uss.mState = UserStartedState.STATE_SHUTDOWN;
14451                        }
14452                        broadcastIntentLocked(null, null, shutdownIntent,
14453                                null, shutdownReceiver, 0, null, null, null,
14454                                true, false, MY_PID, Process.SYSTEM_UID, userId);
14455                    }
14456                };
14457                // Kick things off.
14458                broadcastIntentLocked(null, null, stoppingIntent,
14459                        null, stoppingReceiver, 0, null, null,
14460                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14461                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14462            } finally {
14463                Binder.restoreCallingIdentity(ident);
14464            }
14465        }
14466
14467        return ActivityManager.USER_OP_SUCCESS;
14468    }
14469
14470    void finishUserStop(UserStartedState uss) {
14471        final int userId = uss.mHandle.getIdentifier();
14472        boolean stopped;
14473        ArrayList<IStopUserCallback> callbacks;
14474        synchronized (this) {
14475            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14476            if (mStartedUsers.get(userId) != uss) {
14477                stopped = false;
14478            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14479                stopped = false;
14480            } else {
14481                stopped = true;
14482                // User can no longer run.
14483                mStartedUsers.remove(userId);
14484                mUserLru.remove(Integer.valueOf(userId));
14485                updateStartedUserArrayLocked();
14486
14487                // Clean up all state and processes associated with the user.
14488                // Kill all the processes for the user.
14489                forceStopUserLocked(userId);
14490            }
14491        }
14492
14493        for (int i=0; i<callbacks.size(); i++) {
14494            try {
14495                if (stopped) callbacks.get(i).userStopped(userId);
14496                else callbacks.get(i).userStopAborted(userId);
14497            } catch (RemoteException e) {
14498            }
14499        }
14500    }
14501
14502    @Override
14503    public UserInfo getCurrentUser() {
14504        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14505                != PackageManager.PERMISSION_GRANTED) && (
14506                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14507                != PackageManager.PERMISSION_GRANTED)) {
14508            String msg = "Permission Denial: getCurrentUser() from pid="
14509                    + Binder.getCallingPid()
14510                    + ", uid=" + Binder.getCallingUid()
14511                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14512            Slog.w(TAG, msg);
14513            throw new SecurityException(msg);
14514        }
14515        synchronized (this) {
14516            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14517        }
14518    }
14519
14520    int getCurrentUserIdLocked() {
14521        return mCurrentUserId;
14522    }
14523
14524    @Override
14525    public boolean isUserRunning(int userId, boolean orStopped) {
14526        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14527                != PackageManager.PERMISSION_GRANTED) {
14528            String msg = "Permission Denial: isUserRunning() from pid="
14529                    + Binder.getCallingPid()
14530                    + ", uid=" + Binder.getCallingUid()
14531                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14532            Slog.w(TAG, msg);
14533            throw new SecurityException(msg);
14534        }
14535        synchronized (this) {
14536            return isUserRunningLocked(userId, orStopped);
14537        }
14538    }
14539
14540    boolean isUserRunningLocked(int userId, boolean orStopped) {
14541        UserStartedState state = mStartedUsers.get(userId);
14542        if (state == null) {
14543            return false;
14544        }
14545        if (orStopped) {
14546            return true;
14547        }
14548        return state.mState != UserStartedState.STATE_STOPPING
14549                && state.mState != UserStartedState.STATE_SHUTDOWN;
14550    }
14551
14552    @Override
14553    public int[] getRunningUserIds() {
14554        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14555                != PackageManager.PERMISSION_GRANTED) {
14556            String msg = "Permission Denial: isUserRunning() from pid="
14557                    + Binder.getCallingPid()
14558                    + ", uid=" + Binder.getCallingUid()
14559                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14560            Slog.w(TAG, msg);
14561            throw new SecurityException(msg);
14562        }
14563        synchronized (this) {
14564            return mStartedUserArray;
14565        }
14566    }
14567
14568    private void updateStartedUserArrayLocked() {
14569        int num = 0;
14570        for (int i=0; i<mStartedUsers.size();  i++) {
14571            UserStartedState uss = mStartedUsers.valueAt(i);
14572            // This list does not include stopping users.
14573            if (uss.mState != UserStartedState.STATE_STOPPING
14574                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14575                num++;
14576            }
14577        }
14578        mStartedUserArray = new int[num];
14579        num = 0;
14580        for (int i=0; i<mStartedUsers.size();  i++) {
14581            UserStartedState uss = mStartedUsers.valueAt(i);
14582            if (uss.mState != UserStartedState.STATE_STOPPING
14583                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14584                mStartedUserArray[num] = mStartedUsers.keyAt(i);
14585                num++;
14586            }
14587        }
14588    }
14589
14590    @Override
14591    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14592        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14593                != PackageManager.PERMISSION_GRANTED) {
14594            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14595                    + Binder.getCallingPid()
14596                    + ", uid=" + Binder.getCallingUid()
14597                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14598            Slog.w(TAG, msg);
14599            throw new SecurityException(msg);
14600        }
14601
14602        mUserSwitchObservers.register(observer);
14603    }
14604
14605    @Override
14606    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14607        mUserSwitchObservers.unregister(observer);
14608    }
14609
14610    private boolean userExists(int userId) {
14611        if (userId == 0) {
14612            return true;
14613        }
14614        UserManagerService ums = getUserManagerLocked();
14615        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14616    }
14617
14618    int[] getUsersLocked() {
14619        UserManagerService ums = getUserManagerLocked();
14620        return ums != null ? ums.getUserIds() : new int[] { 0 };
14621    }
14622
14623    UserManagerService getUserManagerLocked() {
14624        if (mUserManager == null) {
14625            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14626            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14627        }
14628        return mUserManager;
14629    }
14630
14631    private void checkValidCaller(int uid, int userId) {
14632        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14633
14634        throw new SecurityException("Caller uid=" + uid
14635                + " is not privileged to communicate with user=" + userId);
14636    }
14637
14638    private int applyUserId(int uid, int userId) {
14639        return UserHandle.getUid(userId, uid);
14640    }
14641
14642    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14643        if (info == null) return null;
14644        ApplicationInfo newInfo = new ApplicationInfo(info);
14645        newInfo.uid = applyUserId(info.uid, userId);
14646        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14647                + info.packageName;
14648        return newInfo;
14649    }
14650
14651    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14652        if (aInfo == null
14653                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14654            return aInfo;
14655        }
14656
14657        ActivityInfo info = new ActivityInfo(aInfo);
14658        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14659        return info;
14660    }
14661}
14662