ActivityManagerService.java revision c0bd747b0605af251ff136277f14220a5a4c9818
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.internal.widget.LockPatternUtils;
25import com.android.server.AttributeCache;
26import com.android.server.IntentResolver;
27import com.android.server.ProcessMap;
28import com.android.server.SystemServer;
29import com.android.server.Watchdog;
30import com.android.server.am.ActivityStack.ActivityState;
31import com.android.server.pm.UserManagerService;
32import com.android.server.wm.WindowManagerService;
33
34import dalvik.system.Zygote;
35
36import android.app.Activity;
37import android.app.ActivityManager;
38import android.app.ActivityManagerNative;
39import android.app.ActivityOptions;
40import android.app.ActivityThread;
41import android.app.AlertDialog;
42import android.app.AppGlobals;
43import android.app.ApplicationErrorReport;
44import android.app.Dialog;
45import android.app.IActivityController;
46import android.app.IApplicationThread;
47import android.app.IInstrumentationWatcher;
48import android.app.INotificationManager;
49import android.app.IProcessObserver;
50import android.app.IServiceConnection;
51import android.app.IStopUserCallback;
52import android.app.IThumbnailReceiver;
53import android.app.IUserSwitchObserver;
54import android.app.Instrumentation;
55import android.app.Notification;
56import android.app.NotificationManager;
57import android.app.PendingIntent;
58import android.app.backup.IBackupManager;
59import android.content.ActivityNotFoundException;
60import android.content.BroadcastReceiver;
61import android.content.ClipData;
62import android.content.ComponentCallbacks2;
63import android.content.ComponentName;
64import android.content.ContentProvider;
65import android.content.ContentResolver;
66import android.content.Context;
67import android.content.DialogInterface;
68import android.content.IContentProvider;
69import android.content.IIntentReceiver;
70import android.content.IIntentSender;
71import android.content.Intent;
72import android.content.IntentFilter;
73import android.content.IntentSender;
74import android.content.pm.ActivityInfo;
75import android.content.pm.ApplicationInfo;
76import android.content.pm.ConfigurationInfo;
77import android.content.pm.IPackageDataObserver;
78import android.content.pm.IPackageManager;
79import android.content.pm.InstrumentationInfo;
80import android.content.pm.PackageInfo;
81import android.content.pm.PackageManager;
82import android.content.pm.UserInfo;
83import android.content.pm.PackageManager.NameNotFoundException;
84import android.content.pm.PathPermission;
85import android.content.pm.ProviderInfo;
86import android.content.pm.ResolveInfo;
87import android.content.pm.ServiceInfo;
88import android.content.res.CompatibilityInfo;
89import android.content.res.Configuration;
90import android.graphics.Bitmap;
91import android.net.Proxy;
92import android.net.ProxyProperties;
93import android.net.Uri;
94import android.os.Binder;
95import android.os.Build;
96import android.os.Bundle;
97import android.os.Debug;
98import android.os.DropBoxManager;
99import android.os.Environment;
100import android.os.FileObserver;
101import android.os.FileUtils;
102import android.os.Handler;
103import android.os.IBinder;
104import android.os.IPermissionController;
105import android.os.IRemoteCallback;
106import android.os.IUserManager;
107import android.os.Looper;
108import android.os.Message;
109import android.os.Parcel;
110import android.os.ParcelFileDescriptor;
111import android.os.Process;
112import android.os.RemoteCallbackList;
113import android.os.RemoteException;
114import android.os.SELinux;
115import android.os.ServiceManager;
116import android.os.StrictMode;
117import android.os.SystemClock;
118import android.os.SystemProperties;
119import android.os.UserHandle;
120import android.provider.Settings;
121import android.text.format.Time;
122import android.util.EventLog;
123import android.util.Log;
124import android.util.Pair;
125import android.util.PrintWriterPrinter;
126import android.util.Slog;
127import android.util.SparseArray;
128import android.util.TimeUtils;
129import android.view.Gravity;
130import android.view.LayoutInflater;
131import android.view.View;
132import android.view.WindowManager;
133import android.view.WindowManagerPolicy;
134
135import java.io.BufferedInputStream;
136import java.io.BufferedOutputStream;
137import java.io.BufferedReader;
138import java.io.DataInputStream;
139import java.io.DataOutputStream;
140import java.io.File;
141import java.io.FileDescriptor;
142import java.io.FileInputStream;
143import java.io.FileNotFoundException;
144import java.io.FileOutputStream;
145import java.io.IOException;
146import java.io.InputStreamReader;
147import java.io.PrintWriter;
148import java.io.StringWriter;
149import java.lang.ref.WeakReference;
150import java.util.ArrayList;
151import java.util.Arrays;
152import java.util.Collections;
153import java.util.Comparator;
154import java.util.HashMap;
155import java.util.HashSet;
156import java.util.Iterator;
157import java.util.List;
158import java.util.Locale;
159import java.util.Map;
160import java.util.Set;
161import java.util.concurrent.atomic.AtomicBoolean;
162import java.util.concurrent.atomic.AtomicLong;
163
164public final class ActivityManagerService extends ActivityManagerNative
165        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
166    private static final String USER_DATA_DIR = "/data/user/";
167    static final String TAG = "ActivityManager";
168    static final String TAG_MU = "ActivityManagerServiceMU";
169    static final boolean DEBUG = false;
170    static final boolean localLOGV = DEBUG;
171    static final boolean DEBUG_SWITCH = localLOGV || false;
172    static final boolean DEBUG_TASKS = localLOGV || false;
173    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
174    static final boolean DEBUG_PAUSE = localLOGV || false;
175    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176    static final boolean DEBUG_TRANSITION = localLOGV || false;
177    static final boolean DEBUG_BROADCAST = localLOGV || false;
178    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
180    static final boolean DEBUG_SERVICE = localLOGV || false;
181    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
182    static final boolean DEBUG_VISBILITY = localLOGV || false;
183    static final boolean DEBUG_PROCESSES = localLOGV || false;
184    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
185    static final boolean DEBUG_CLEANUP = localLOGV || false;
186    static final boolean DEBUG_PROVIDER = localLOGV || false;
187    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
188    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
189    static final boolean DEBUG_RESULTS = localLOGV || false;
190    static final boolean DEBUG_BACKUP = localLOGV || false;
191    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
192    static final boolean DEBUG_POWER = localLOGV || false;
193    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
194    static final boolean DEBUG_MU = localLOGV || false;
195    static final boolean VALIDATE_TOKENS = false;
196    static final boolean SHOW_ACTIVITY_START_TIME = true;
197
198    // Control over CPU and battery monitoring.
199    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
200    static final boolean MONITOR_CPU_USAGE = true;
201    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
202    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
203    static final boolean MONITOR_THREAD_CPU_USAGE = false;
204
205    // The flags that are set for all calls we make to the package manager.
206    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
207
208    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
209
210    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
211
212    // Maximum number of recent tasks that we can remember.
213    static final int MAX_RECENT_TASKS = 20;
214
215    // Amount of time after a call to stopAppSwitches() during which we will
216    // prevent further untrusted switches from happening.
217    static final long APP_SWITCH_DELAY_TIME = 5*1000;
218
219    // How long we wait for a launched process to attach to the activity manager
220    // before we decide it's never going to come up for real.
221    static final int PROC_START_TIMEOUT = 10*1000;
222
223    // How long we wait for a launched process to attach to the activity manager
224    // before we decide it's never going to come up for real, when the process was
225    // started with a wrapper for instrumentation (such as Valgrind) because it
226    // could take much longer than usual.
227    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
228
229    // How long to wait after going idle before forcing apps to GC.
230    static final int GC_TIMEOUT = 5*1000;
231
232    // The minimum amount of time between successive GC requests for a process.
233    static final int GC_MIN_INTERVAL = 60*1000;
234
235    // The rate at which we check for apps using excessive power -- 15 mins.
236    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on wake locks to start killing things.
240    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // The minimum sample duration we will allow before deciding we have
243    // enough data on CPU usage to start killing things.
244    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
245
246    // How long we allow a receiver to run before giving up on it.
247    static final int BROADCAST_FG_TIMEOUT = 10*1000;
248    static final int BROADCAST_BG_TIMEOUT = 60*1000;
249
250    // How long we wait until we timeout on key dispatching.
251    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
252
253    // How long we wait until we timeout on key dispatching during instrumentation.
254    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
255
256    // Amount of time we wait for observers to handle a user switch before
257    // giving up on them and unfreezing the screen.
258    static final int USER_SWITCH_TIMEOUT = 2*1000;
259
260    // Maximum number of users we allow to be running at a time.
261    static final int MAX_RUNNING_USERS = 3;
262
263    static final int MY_PID = Process.myPid();
264
265    static final String[] EMPTY_STRING_ARRAY = new String[0];
266
267    public ActivityStack mMainStack;
268
269    private final boolean mHeadless;
270
271    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
272    // default actuion automatically.  Important for devices without direct input
273    // devices.
274    private boolean mShowDialogs = true;
275
276    /**
277     * Description of a request to start a new activity, which has been held
278     * due to app switches being disabled.
279     */
280    static class PendingActivityLaunch {
281        ActivityRecord r;
282        ActivityRecord sourceRecord;
283        int startFlags;
284    }
285
286    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
287            = new ArrayList<PendingActivityLaunch>();
288
289
290    BroadcastQueue mFgBroadcastQueue;
291    BroadcastQueue mBgBroadcastQueue;
292    // Convenient for easy iteration over the queues. Foreground is first
293    // so that dispatch of foreground broadcasts gets precedence.
294    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
295
296    BroadcastQueue broadcastQueueForIntent(Intent intent) {
297        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
298        if (DEBUG_BACKGROUND_BROADCAST) {
299            Slog.i(TAG, "Broadcast intent " + intent + " on "
300                    + (isFg ? "foreground" : "background")
301                    + " queue");
302        }
303        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
304    }
305
306    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
307        for (BroadcastQueue queue : mBroadcastQueues) {
308            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
309            if (r != null) {
310                return r;
311            }
312        }
313        return null;
314    }
315
316    /**
317     * Activity we have told the window manager to have key focus.
318     */
319    ActivityRecord mFocusedActivity = null;
320    /**
321     * List of intents that were used to start the most recent tasks.
322     */
323    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
324
325    /**
326     * Process management.
327     */
328    final ProcessList mProcessList = new ProcessList();
329
330    /**
331     * All of the applications we currently have running organized by name.
332     * The keys are strings of the application package name (as
333     * returned by the package manager), and the keys are ApplicationRecord
334     * objects.
335     */
336    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
337
338    /**
339     * The currently running isolated processes.
340     */
341    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
342
343    /**
344     * Counter for assigning isolated process uids, to avoid frequently reusing the
345     * same ones.
346     */
347    int mNextIsolatedProcessUid = 0;
348
349    /**
350     * The currently running heavy-weight process, if any.
351     */
352    ProcessRecord mHeavyWeightProcess = null;
353
354    /**
355     * The last time that various processes have crashed.
356     */
357    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
358
359    /**
360     * Set of applications that we consider to be bad, and will reject
361     * incoming broadcasts from (which the user has no control over).
362     * Processes are added to this set when they have crashed twice within
363     * a minimum amount of time; they are removed from it when they are
364     * later restarted (hopefully due to some user action).  The value is the
365     * time it was added to the list.
366     */
367    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
368
369    /**
370     * All of the processes we currently have running organized by pid.
371     * The keys are the pid running the application.
372     *
373     * <p>NOTE: This object is protected by its own lock, NOT the global
374     * activity manager lock!
375     */
376    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
377
378    /**
379     * All of the processes that have been forced to be foreground.  The key
380     * is the pid of the caller who requested it (we hold a death
381     * link on it).
382     */
383    abstract class ForegroundToken implements IBinder.DeathRecipient {
384        int pid;
385        IBinder token;
386    }
387    final SparseArray<ForegroundToken> mForegroundProcesses
388            = new SparseArray<ForegroundToken>();
389
390    /**
391     * List of records for processes that someone had tried to start before the
392     * system was ready.  We don't start them at that point, but ensure they
393     * are started by the time booting is complete.
394     */
395    final ArrayList<ProcessRecord> mProcessesOnHold
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of persistent applications that are in the process
400     * of being started.
401     */
402    final ArrayList<ProcessRecord> mPersistentStartingProcesses
403            = new ArrayList<ProcessRecord>();
404
405    /**
406     * Processes that are being forcibly torn down.
407     */
408    final ArrayList<ProcessRecord> mRemovedProcesses
409            = new ArrayList<ProcessRecord>();
410
411    /**
412     * List of running applications, sorted by recent usage.
413     * The first entry in the list is the least recently used.
414     * It contains ApplicationRecord objects.  This list does NOT include
415     * any persistent application records (since we never want to exit them).
416     */
417    final ArrayList<ProcessRecord> mLruProcesses
418            = new ArrayList<ProcessRecord>();
419
420    /**
421     * List of processes that should gc as soon as things are idle.
422     */
423    final ArrayList<ProcessRecord> mProcessesToGc
424            = new ArrayList<ProcessRecord>();
425
426    /**
427     * This is the process holding what we currently consider to be
428     * the "home" activity.
429     */
430    ProcessRecord mHomeProcess;
431
432    /**
433     * This is the process holding the activity the user last visited that
434     * is in a different process from the one they are currently in.
435     */
436    ProcessRecord mPreviousProcess;
437
438    /**
439     * The time at which the previous process was last visible.
440     */
441    long mPreviousProcessVisibleTime;
442
443    /**
444     * Which uses have been started, so are allowed to run code.
445     */
446    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
447
448    /**
449     * LRU list of history of current users.  Most recently current is at the end.
450     */
451    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
452
453    /**
454     * Constant array of the users that are currently started.
455     */
456    int[] mStartedUserArray = new int[] { 0 };
457
458    /**
459     * Registered observers of the user switching mechanics.
460     */
461    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
462            = new RemoteCallbackList<IUserSwitchObserver>();
463
464    /**
465     * Currently active user switch.
466     */
467    Object mCurUserSwitchCallback;
468
469    /**
470     * Packages that the user has asked to have run in screen size
471     * compatibility mode instead of filling the screen.
472     */
473    final CompatModePackages mCompatModePackages;
474
475    /**
476     * Set of PendingResultRecord objects that are currently active.
477     */
478    final HashSet mPendingResultRecords = new HashSet();
479
480    /**
481     * Set of IntentSenderRecord objects that are currently active.
482     */
483    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
484            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
485
486    /**
487     * Fingerprints (hashCode()) of stack traces that we've
488     * already logged DropBox entries for.  Guarded by itself.  If
489     * something (rogue user app) forces this over
490     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
491     */
492    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
493    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
494
495    /**
496     * Strict Mode background batched logging state.
497     *
498     * The string buffer is guarded by itself, and its lock is also
499     * used to determine if another batched write is already
500     * in-flight.
501     */
502    private final StringBuilder mStrictModeBuffer = new StringBuilder();
503
504    /**
505     * Keeps track of all IIntentReceivers that have been registered for
506     * broadcasts.  Hash keys are the receiver IBinder, hash value is
507     * a ReceiverList.
508     */
509    final HashMap mRegisteredReceivers = new HashMap();
510
511    /**
512     * Resolver for broadcast intents to registered receivers.
513     * Holds BroadcastFilter (subclass of IntentFilter).
514     */
515    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
516            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
517        @Override
518        protected boolean allowFilterResult(
519                BroadcastFilter filter, List<BroadcastFilter> dest) {
520            IBinder target = filter.receiverList.receiver.asBinder();
521            for (int i=dest.size()-1; i>=0; i--) {
522                if (dest.get(i).receiverList.receiver.asBinder() == target) {
523                    return false;
524                }
525            }
526            return true;
527        }
528
529        @Override
530        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
531            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
532                    || userId == filter.owningUserId) {
533                return super.newResult(filter, match, userId);
534            }
535            return null;
536        }
537
538        @Override
539        protected BroadcastFilter[] newArray(int size) {
540            return new BroadcastFilter[size];
541        }
542
543        @Override
544        protected String packageForFilter(BroadcastFilter filter) {
545            return filter.packageName;
546        }
547    };
548
549    /**
550     * State of all active sticky broadcasts per user.  Keys are the action of the
551     * sticky Intent, values are an ArrayList of all broadcasted intents with
552     * that action (which should usually be one).  The SparseArray is keyed
553     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
554     * for stickies that are sent to all users.
555     */
556    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
557            new SparseArray<HashMap<String, ArrayList<Intent>>>();
558
559    final ActiveServices mServices;
560
561    /**
562     * Backup/restore process management
563     */
564    String mBackupAppName = null;
565    BackupRecord mBackupTarget = null;
566
567    /**
568     * List of PendingThumbnailsRecord objects of clients who are still
569     * waiting to receive all of the thumbnails for a task.
570     */
571    final ArrayList mPendingThumbnails = new ArrayList();
572
573    /**
574     * List of HistoryRecord objects that have been finished and must
575     * still report back to a pending thumbnail receiver.
576     */
577    final ArrayList mCancelledThumbnails = new ArrayList();
578
579    final ProviderMap mProviderMap;
580
581    /**
582     * List of content providers who have clients waiting for them.  The
583     * application is currently being launched and the provider will be
584     * removed from this list once it is published.
585     */
586    final ArrayList<ContentProviderRecord> mLaunchingProviders
587            = new ArrayList<ContentProviderRecord>();
588
589    /**
590     * Global set of specific Uri permissions that have been granted.
591     */
592    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
593            = new SparseArray<HashMap<Uri, UriPermission>>();
594
595    CoreSettingsObserver mCoreSettingsObserver;
596
597    /**
598     * Thread-local storage used to carry caller permissions over through
599     * indirect content-provider access.
600     * @see #ActivityManagerService.openContentUri()
601     */
602    private class Identity {
603        public int pid;
604        public int uid;
605
606        Identity(int _pid, int _uid) {
607            pid = _pid;
608            uid = _uid;
609        }
610    }
611
612    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
613
614    /**
615     * All information we have collected about the runtime performance of
616     * any user id that can impact battery performance.
617     */
618    final BatteryStatsService mBatteryStatsService;
619
620    /**
621     * information about component usage
622     */
623    final UsageStatsService mUsageStatsService;
624
625    /**
626     * Current configuration information.  HistoryRecord objects are given
627     * a reference to this object to indicate which configuration they are
628     * currently running in, so this object must be kept immutable.
629     */
630    Configuration mConfiguration = new Configuration();
631
632    /**
633     * Current sequencing integer of the configuration, for skipping old
634     * configurations.
635     */
636    int mConfigurationSeq = 0;
637
638    /**
639     * Hardware-reported OpenGLES version.
640     */
641    final int GL_ES_VERSION;
642
643    /**
644     * List of initialization arguments to pass to all processes when binding applications to them.
645     * For example, references to the commonly used services.
646     */
647    HashMap<String, IBinder> mAppBindArgs;
648
649    /**
650     * Temporary to avoid allocations.  Protected by main lock.
651     */
652    final StringBuilder mStringBuilder = new StringBuilder(256);
653
654    /**
655     * Used to control how we initialize the service.
656     */
657    boolean mStartRunning = false;
658    ComponentName mTopComponent;
659    String mTopAction;
660    String mTopData;
661    boolean mProcessesReady = false;
662    boolean mSystemReady = false;
663    boolean mBooting = false;
664    boolean mWaitingUpdate = false;
665    boolean mDidUpdate = false;
666    boolean mOnBattery = false;
667    boolean mLaunchWarningShown = false;
668
669    Context mContext;
670
671    int mFactoryTest;
672
673    boolean mCheckedForSetup;
674
675    /**
676     * The time at which we will allow normal application switches again,
677     * after a call to {@link #stopAppSwitches()}.
678     */
679    long mAppSwitchesAllowedTime;
680
681    /**
682     * This is set to true after the first switch after mAppSwitchesAllowedTime
683     * is set; any switches after that will clear the time.
684     */
685    boolean mDidAppSwitch;
686
687    /**
688     * Last time (in realtime) at which we checked for power usage.
689     */
690    long mLastPowerCheckRealtime;
691
692    /**
693     * Last time (in uptime) at which we checked for power usage.
694     */
695    long mLastPowerCheckUptime;
696
697    /**
698     * Set while we are wanting to sleep, to prevent any
699     * activities from being started/resumed.
700     */
701    boolean mSleeping = false;
702
703    /**
704     * State of external calls telling us if the device is asleep.
705     */
706    boolean mWentToSleep = false;
707
708    /**
709     * State of external call telling us if the lock screen is shown.
710     */
711    boolean mLockScreenShown = false;
712
713    /**
714     * Set if we are shutting down the system, similar to sleeping.
715     */
716    boolean mShuttingDown = false;
717
718    /**
719     * Task identifier that activities are currently being started
720     * in.  Incremented each time a new task is created.
721     * todo: Replace this with a TokenSpace class that generates non-repeating
722     * integers that won't wrap.
723     */
724    int mCurTask = 1;
725
726    /**
727     * Current sequence id for oom_adj computation traversal.
728     */
729    int mAdjSeq = 0;
730
731    /**
732     * Current sequence id for process LRU updating.
733     */
734    int mLruSeq = 0;
735
736    /**
737     * Keep track of the non-hidden/empty process we last found, to help
738     * determine how to distribute hidden/empty processes next time.
739     */
740    int mNumNonHiddenProcs = 0;
741
742    /**
743     * Keep track of the number of hidden procs, to balance oom adj
744     * distribution between those and empty procs.
745     */
746    int mNumHiddenProcs = 0;
747
748    /**
749     * Keep track of the number of service processes we last found, to
750     * determine on the next iteration which should be B services.
751     */
752    int mNumServiceProcs = 0;
753    int mNewNumServiceProcs = 0;
754
755    /**
756     * System monitoring: number of processes that died since the last
757     * N procs were started.
758     */
759    int[] mProcDeaths = new int[20];
760
761    /**
762     * This is set if we had to do a delayed dexopt of an app before launching
763     * it, to increasing the ANR timeouts in that case.
764     */
765    boolean mDidDexOpt;
766
767    String mDebugApp = null;
768    boolean mWaitForDebugger = false;
769    boolean mDebugTransient = false;
770    String mOrigDebugApp = null;
771    boolean mOrigWaitForDebugger = false;
772    boolean mAlwaysFinishActivities = false;
773    IActivityController mController = null;
774    String mProfileApp = null;
775    ProcessRecord mProfileProc = null;
776    String mProfileFile;
777    ParcelFileDescriptor mProfileFd;
778    int mProfileType = 0;
779    boolean mAutoStopProfiler = false;
780    String mOpenGlTraceApp = null;
781
782    static class ProcessChangeItem {
783        static final int CHANGE_ACTIVITIES = 1<<0;
784        static final int CHANGE_IMPORTANCE= 1<<1;
785        int changes;
786        int uid;
787        int pid;
788        int importance;
789        boolean foregroundActivities;
790    }
791
792    final RemoteCallbackList<IProcessObserver> mProcessObservers
793            = new RemoteCallbackList<IProcessObserver>();
794    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
795
796    final ArrayList<ProcessChangeItem> mPendingProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798    final ArrayList<ProcessChangeItem> mAvailProcessChanges
799            = new ArrayList<ProcessChangeItem>();
800
801    /**
802     * Callback of last caller to {@link #requestPss}.
803     */
804    Runnable mRequestPssCallback;
805
806    /**
807     * Remaining processes for which we are waiting results from the last
808     * call to {@link #requestPss}.
809     */
810    final ArrayList<ProcessRecord> mRequestPssList
811            = new ArrayList<ProcessRecord>();
812
813    /**
814     * Runtime statistics collection thread.  This object's lock is used to
815     * protect all related state.
816     */
817    final Thread mProcessStatsThread;
818
819    /**
820     * Used to collect process stats when showing not responding dialog.
821     * Protected by mProcessStatsThread.
822     */
823    final ProcessStats mProcessStats = new ProcessStats(
824            MONITOR_THREAD_CPU_USAGE);
825    final AtomicLong mLastCpuTime = new AtomicLong(0);
826    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
827
828    long mLastWriteTime = 0;
829
830    /**
831     * Set to true after the system has finished booting.
832     */
833    boolean mBooted = false;
834
835    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
836    int mProcessLimitOverride = -1;
837
838    WindowManagerService mWindowManager;
839
840    static ActivityManagerService mSelf;
841    static ActivityThread mSystemThread;
842
843    private int mCurrentUserId = 0;
844    private int[] mCurrentUserArray = new int[] { 0 };
845    private UserManagerService mUserManager;
846
847    private final class AppDeathRecipient implements IBinder.DeathRecipient {
848        final ProcessRecord mApp;
849        final int mPid;
850        final IApplicationThread mAppThread;
851
852        AppDeathRecipient(ProcessRecord app, int pid,
853                IApplicationThread thread) {
854            if (localLOGV) Slog.v(
855                TAG, "New death recipient " + this
856                + " for thread " + thread.asBinder());
857            mApp = app;
858            mPid = pid;
859            mAppThread = thread;
860        }
861
862        public void binderDied() {
863            if (localLOGV) Slog.v(
864                TAG, "Death received in " + this
865                + " for thread " + mAppThread.asBinder());
866            synchronized(ActivityManagerService.this) {
867                appDiedLocked(mApp, mPid, mAppThread);
868            }
869        }
870    }
871
872    static final int SHOW_ERROR_MSG = 1;
873    static final int SHOW_NOT_RESPONDING_MSG = 2;
874    static final int SHOW_FACTORY_ERROR_MSG = 3;
875    static final int UPDATE_CONFIGURATION_MSG = 4;
876    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
877    static final int WAIT_FOR_DEBUGGER_MSG = 6;
878    static final int SERVICE_TIMEOUT_MSG = 12;
879    static final int UPDATE_TIME_ZONE = 13;
880    static final int SHOW_UID_ERROR_MSG = 14;
881    static final int IM_FEELING_LUCKY_MSG = 15;
882    static final int PROC_START_TIMEOUT_MSG = 20;
883    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
884    static final int KILL_APPLICATION_MSG = 22;
885    static final int FINALIZE_PENDING_INTENT_MSG = 23;
886    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
887    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
888    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
889    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
890    static final int CLEAR_DNS_CACHE = 28;
891    static final int UPDATE_HTTP_PROXY = 29;
892    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
893    static final int DISPATCH_PROCESSES_CHANGED = 31;
894    static final int DISPATCH_PROCESS_DIED = 32;
895    static final int REPORT_MEM_USAGE = 33;
896    static final int REPORT_USER_SWITCH_MSG = 34;
897    static final int CONTINUE_USER_SWITCH_MSG = 35;
898    static final int USER_SWITCH_TIMEOUT_MSG = 36;
899
900    static final int FIRST_ACTIVITY_STACK_MSG = 100;
901    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
902    static final int FIRST_COMPAT_MODE_MSG = 300;
903
904    AlertDialog mUidAlert;
905    CompatModeDialog mCompatModeDialog;
906    long mLastMemUsageReportTime = 0;
907
908    final Handler mHandler = new Handler() {
909        //public Handler() {
910        //    if (localLOGV) Slog.v(TAG, "Handler started!");
911        //}
912
913        public void handleMessage(Message msg) {
914            switch (msg.what) {
915            case SHOW_ERROR_MSG: {
916                HashMap data = (HashMap) msg.obj;
917                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
918                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
919                synchronized (ActivityManagerService.this) {
920                    ProcessRecord proc = (ProcessRecord)data.get("app");
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (proc != null && proc.crashDialog != null) {
923                        Slog.e(TAG, "App already has crash dialog: " + proc);
924                        if (res != null) {
925                            res.set(0);
926                        }
927                        return;
928                    }
929                    if (!showBackground && UserHandle.getAppId(proc.uid)
930                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
931                            && proc.pid != MY_PID) {
932                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
933                        if (res != null) {
934                            res.set(0);
935                        }
936                        return;
937                    }
938                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
939                        Dialog d = new AppErrorDialog(mContext,
940                                ActivityManagerService.this, res, proc);
941                        d.show();
942                        proc.crashDialog = d;
943                    } else {
944                        // The device is asleep, so just pretend that the user
945                        // saw a crash dialog and hit "force quit".
946                        if (res != null) {
947                            res.set(0);
948                        }
949                    }
950                }
951
952                ensureBootCompleted();
953            } break;
954            case SHOW_NOT_RESPONDING_MSG: {
955                synchronized (ActivityManagerService.this) {
956                    HashMap data = (HashMap) msg.obj;
957                    ProcessRecord proc = (ProcessRecord)data.get("app");
958                    if (proc != null && proc.anrDialog != null) {
959                        Slog.e(TAG, "App already has anr dialog: " + proc);
960                        return;
961                    }
962
963                    Intent intent = new Intent("android.intent.action.ANR");
964                    if (!mProcessesReady) {
965                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
966                                | Intent.FLAG_RECEIVER_FOREGROUND);
967                    }
968                    broadcastIntentLocked(null, null, intent,
969                            null, null, 0, null, null, null,
970                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
971
972                    if (mShowDialogs) {
973                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
974                                mContext, proc, (ActivityRecord)data.get("activity"),
975                                msg.arg1 != 0);
976                        d.show();
977                        proc.anrDialog = d;
978                    } else {
979                        // Just kill the app if there is no dialog to be shown.
980                        killAppAtUsersRequest(proc, null);
981                    }
982                }
983
984                ensureBootCompleted();
985            } break;
986            case SHOW_STRICT_MODE_VIOLATION_MSG: {
987                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
988                synchronized (ActivityManagerService.this) {
989                    ProcessRecord proc = (ProcessRecord) data.get("app");
990                    if (proc == null) {
991                        Slog.e(TAG, "App not found when showing strict mode dialog.");
992                        break;
993                    }
994                    if (proc.crashDialog != null) {
995                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
996                        return;
997                    }
998                    AppErrorResult res = (AppErrorResult) data.get("result");
999                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1000                        Dialog d = new StrictModeViolationDialog(mContext,
1001                                ActivityManagerService.this, res, proc);
1002                        d.show();
1003                        proc.crashDialog = d;
1004                    } else {
1005                        // The device is asleep, so just pretend that the user
1006                        // saw a crash dialog and hit "force quit".
1007                        res.set(0);
1008                    }
1009                }
1010                ensureBootCompleted();
1011            } break;
1012            case SHOW_FACTORY_ERROR_MSG: {
1013                Dialog d = new FactoryErrorDialog(
1014                    mContext, msg.getData().getCharSequence("msg"));
1015                d.show();
1016                ensureBootCompleted();
1017            } break;
1018            case UPDATE_CONFIGURATION_MSG: {
1019                final ContentResolver resolver = mContext.getContentResolver();
1020                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1021            } break;
1022            case GC_BACKGROUND_PROCESSES_MSG: {
1023                synchronized (ActivityManagerService.this) {
1024                    performAppGcsIfAppropriateLocked();
1025                }
1026            } break;
1027            case WAIT_FOR_DEBUGGER_MSG: {
1028                synchronized (ActivityManagerService.this) {
1029                    ProcessRecord app = (ProcessRecord)msg.obj;
1030                    if (msg.arg1 != 0) {
1031                        if (!app.waitedForDebugger) {
1032                            Dialog d = new AppWaitingForDebuggerDialog(
1033                                    ActivityManagerService.this,
1034                                    mContext, app);
1035                            app.waitDialog = d;
1036                            app.waitedForDebugger = true;
1037                            d.show();
1038                        }
1039                    } else {
1040                        if (app.waitDialog != null) {
1041                            app.waitDialog.dismiss();
1042                            app.waitDialog = null;
1043                        }
1044                    }
1045                }
1046            } break;
1047            case SERVICE_TIMEOUT_MSG: {
1048                if (mDidDexOpt) {
1049                    mDidDexOpt = false;
1050                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1051                    nmsg.obj = msg.obj;
1052                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1053                    return;
1054                }
1055                mServices.serviceTimeout((ProcessRecord)msg.obj);
1056            } break;
1057            case UPDATE_TIME_ZONE: {
1058                synchronized (ActivityManagerService.this) {
1059                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1060                        ProcessRecord r = mLruProcesses.get(i);
1061                        if (r.thread != null) {
1062                            try {
1063                                r.thread.updateTimeZone();
1064                            } catch (RemoteException ex) {
1065                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1066                            }
1067                        }
1068                    }
1069                }
1070            } break;
1071            case CLEAR_DNS_CACHE: {
1072                synchronized (ActivityManagerService.this) {
1073                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1074                        ProcessRecord r = mLruProcesses.get(i);
1075                        if (r.thread != null) {
1076                            try {
1077                                r.thread.clearDnsCache();
1078                            } catch (RemoteException ex) {
1079                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1080                            }
1081                        }
1082                    }
1083                }
1084            } break;
1085            case UPDATE_HTTP_PROXY: {
1086                ProxyProperties proxy = (ProxyProperties)msg.obj;
1087                String host = "";
1088                String port = "";
1089                String exclList = "";
1090                if (proxy != null) {
1091                    host = proxy.getHost();
1092                    port = Integer.toString(proxy.getPort());
1093                    exclList = proxy.getExclusionList();
1094                }
1095                synchronized (ActivityManagerService.this) {
1096                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1097                        ProcessRecord r = mLruProcesses.get(i);
1098                        if (r.thread != null) {
1099                            try {
1100                                r.thread.setHttpProxy(host, port, exclList);
1101                            } catch (RemoteException ex) {
1102                                Slog.w(TAG, "Failed to update http proxy for: " +
1103                                        r.info.processName);
1104                            }
1105                        }
1106                    }
1107                }
1108            } break;
1109            case SHOW_UID_ERROR_MSG: {
1110                String title = "System UIDs Inconsistent";
1111                String text = "UIDs on the system are inconsistent, you need to wipe your"
1112                        + " data partition or your device will be unstable.";
1113                Log.e(TAG, title + ": " + text);
1114                if (mShowDialogs) {
1115                    // XXX This is a temporary dialog, no need to localize.
1116                    AlertDialog d = new BaseErrorDialog(mContext);
1117                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1118                    d.setCancelable(false);
1119                    d.setTitle(title);
1120                    d.setMessage(text);
1121                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1122                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1123                    mUidAlert = d;
1124                    d.show();
1125                }
1126            } break;
1127            case IM_FEELING_LUCKY_MSG: {
1128                if (mUidAlert != null) {
1129                    mUidAlert.dismiss();
1130                    mUidAlert = null;
1131                }
1132            } break;
1133            case PROC_START_TIMEOUT_MSG: {
1134                if (mDidDexOpt) {
1135                    mDidDexOpt = false;
1136                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1137                    nmsg.obj = msg.obj;
1138                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1139                    return;
1140                }
1141                ProcessRecord app = (ProcessRecord)msg.obj;
1142                synchronized (ActivityManagerService.this) {
1143                    processStartTimedOutLocked(app);
1144                }
1145            } break;
1146            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1147                synchronized (ActivityManagerService.this) {
1148                    doPendingActivityLaunchesLocked(true);
1149                }
1150            } break;
1151            case KILL_APPLICATION_MSG: {
1152                synchronized (ActivityManagerService.this) {
1153                    int appid = msg.arg1;
1154                    boolean restart = (msg.arg2 == 1);
1155                    String pkg = (String) msg.obj;
1156                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1157                            UserHandle.USER_ALL);
1158                }
1159            } break;
1160            case FINALIZE_PENDING_INTENT_MSG: {
1161                ((PendingIntentRecord)msg.obj).completeFinalize();
1162            } break;
1163            case POST_HEAVY_NOTIFICATION_MSG: {
1164                INotificationManager inm = NotificationManager.getService();
1165                if (inm == null) {
1166                    return;
1167                }
1168
1169                ActivityRecord root = (ActivityRecord)msg.obj;
1170                ProcessRecord process = root.app;
1171                if (process == null) {
1172                    return;
1173                }
1174
1175                try {
1176                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1177                    String text = mContext.getString(R.string.heavy_weight_notification,
1178                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1179                    Notification notification = new Notification();
1180                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1181                    notification.when = 0;
1182                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1183                    notification.tickerText = text;
1184                    notification.defaults = 0; // please be quiet
1185                    notification.sound = null;
1186                    notification.vibrate = null;
1187                    notification.setLatestEventInfo(context, text,
1188                            mContext.getText(R.string.heavy_weight_notification_detail),
1189                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1190                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1191                                    new UserHandle(root.userId)));
1192
1193                    try {
1194                        int[] outId = new int[1];
1195                        inm.enqueueNotificationWithTag("android", null,
1196                                R.string.heavy_weight_notification,
1197                                notification, outId, root.userId);
1198                    } catch (RuntimeException e) {
1199                        Slog.w(ActivityManagerService.TAG,
1200                                "Error showing notification for heavy-weight app", e);
1201                    } catch (RemoteException e) {
1202                    }
1203                } catch (NameNotFoundException e) {
1204                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1205                }
1206            } break;
1207            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1208                INotificationManager inm = NotificationManager.getService();
1209                if (inm == null) {
1210                    return;
1211                }
1212                try {
1213                    inm.cancelNotificationWithTag("android", null,
1214                            R.string.heavy_weight_notification,  msg.arg1);
1215                } catch (RuntimeException e) {
1216                    Slog.w(ActivityManagerService.TAG,
1217                            "Error canceling notification for service", e);
1218                } catch (RemoteException e) {
1219                }
1220            } break;
1221            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1222                synchronized (ActivityManagerService.this) {
1223                    checkExcessivePowerUsageLocked(true);
1224                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1225                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1226                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1227                }
1228            } break;
1229            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1230                synchronized (ActivityManagerService.this) {
1231                    ActivityRecord ar = (ActivityRecord)msg.obj;
1232                    if (mCompatModeDialog != null) {
1233                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1234                                ar.info.applicationInfo.packageName)) {
1235                            return;
1236                        }
1237                        mCompatModeDialog.dismiss();
1238                        mCompatModeDialog = null;
1239                    }
1240                    if (ar != null && false) {
1241                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1242                                ar.packageName)) {
1243                            int mode = mCompatModePackages.computeCompatModeLocked(
1244                                    ar.info.applicationInfo);
1245                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1246                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1247                                mCompatModeDialog = new CompatModeDialog(
1248                                        ActivityManagerService.this, mContext,
1249                                        ar.info.applicationInfo);
1250                                mCompatModeDialog.show();
1251                            }
1252                        }
1253                    }
1254                }
1255                break;
1256            }
1257            case DISPATCH_PROCESSES_CHANGED: {
1258                dispatchProcessesChanged();
1259                break;
1260            }
1261            case DISPATCH_PROCESS_DIED: {
1262                final int pid = msg.arg1;
1263                final int uid = msg.arg2;
1264                dispatchProcessDied(pid, uid);
1265                break;
1266            }
1267            case REPORT_MEM_USAGE: {
1268                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1269                if (!isDebuggable) {
1270                    return;
1271                }
1272                synchronized (ActivityManagerService.this) {
1273                    long now = SystemClock.uptimeMillis();
1274                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1275                        // Don't report more than every 5 minutes to somewhat
1276                        // avoid spamming.
1277                        return;
1278                    }
1279                    mLastMemUsageReportTime = now;
1280                }
1281                Thread thread = new Thread() {
1282                    @Override public void run() {
1283                        StringBuilder dropBuilder = new StringBuilder(1024);
1284                        StringBuilder logBuilder = new StringBuilder(1024);
1285                        StringWriter oomSw = new StringWriter();
1286                        PrintWriter oomPw = new PrintWriter(oomSw);
1287                        StringWriter catSw = new StringWriter();
1288                        PrintWriter catPw = new PrintWriter(catSw);
1289                        String[] emptyArgs = new String[] { };
1290                        StringBuilder tag = new StringBuilder(128);
1291                        StringBuilder stack = new StringBuilder(128);
1292                        tag.append("Low on memory -- ");
1293                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1294                                tag, stack);
1295                        dropBuilder.append(stack);
1296                        dropBuilder.append('\n');
1297                        dropBuilder.append('\n');
1298                        String oomString = oomSw.toString();
1299                        dropBuilder.append(oomString);
1300                        dropBuilder.append('\n');
1301                        logBuilder.append(oomString);
1302                        try {
1303                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1304                                    "procrank", });
1305                            final InputStreamReader converter = new InputStreamReader(
1306                                    proc.getInputStream());
1307                            BufferedReader in = new BufferedReader(converter);
1308                            String line;
1309                            while (true) {
1310                                line = in.readLine();
1311                                if (line == null) {
1312                                    break;
1313                                }
1314                                if (line.length() > 0) {
1315                                    logBuilder.append(line);
1316                                    logBuilder.append('\n');
1317                                }
1318                                dropBuilder.append(line);
1319                                dropBuilder.append('\n');
1320                            }
1321                            converter.close();
1322                        } catch (IOException e) {
1323                        }
1324                        synchronized (ActivityManagerService.this) {
1325                            catPw.println();
1326                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1327                            catPw.println();
1328                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1329                                    false, false, null);
1330                            catPw.println();
1331                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1332                        }
1333                        dropBuilder.append(catSw.toString());
1334                        addErrorToDropBox("lowmem", null, "system_server", null,
1335                                null, tag.toString(), dropBuilder.toString(), null, null);
1336                        Slog.i(TAG, logBuilder.toString());
1337                        synchronized (ActivityManagerService.this) {
1338                            long now = SystemClock.uptimeMillis();
1339                            if (mLastMemUsageReportTime < now) {
1340                                mLastMemUsageReportTime = now;
1341                            }
1342                        }
1343                    }
1344                };
1345                thread.start();
1346                break;
1347            }
1348            case REPORT_USER_SWITCH_MSG: {
1349                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1350                break;
1351            }
1352            case CONTINUE_USER_SWITCH_MSG: {
1353                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1354                break;
1355            }
1356            case USER_SWITCH_TIMEOUT_MSG: {
1357                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1358                break;
1359            }
1360            }
1361        }
1362    };
1363
1364    public static void setSystemProcess() {
1365        try {
1366            ActivityManagerService m = mSelf;
1367
1368            ServiceManager.addService("activity", m, true);
1369            ServiceManager.addService("meminfo", new MemBinder(m));
1370            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1371            ServiceManager.addService("dbinfo", new DbBinder(m));
1372            if (MONITOR_CPU_USAGE) {
1373                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1374            }
1375            ServiceManager.addService("permission", new PermissionController(m));
1376
1377            ApplicationInfo info =
1378                mSelf.mContext.getPackageManager().getApplicationInfo(
1379                            "android", STOCK_PM_FLAGS);
1380            mSystemThread.installSystemApplicationInfo(info);
1381
1382            synchronized (mSelf) {
1383                ProcessRecord app = mSelf.newProcessRecordLocked(
1384                        mSystemThread.getApplicationThread(), info,
1385                        info.processName, false);
1386                app.persistent = true;
1387                app.pid = MY_PID;
1388                app.maxAdj = ProcessList.SYSTEM_ADJ;
1389                mSelf.mProcessNames.put(app.processName, app.uid, app);
1390                synchronized (mSelf.mPidsSelfLocked) {
1391                    mSelf.mPidsSelfLocked.put(app.pid, app);
1392                }
1393                mSelf.updateLruProcessLocked(app, true);
1394            }
1395        } catch (PackageManager.NameNotFoundException e) {
1396            throw new RuntimeException(
1397                    "Unable to find android system package", e);
1398        }
1399    }
1400
1401    public void setWindowManager(WindowManagerService wm) {
1402        mWindowManager = wm;
1403    }
1404
1405    public static final Context main(int factoryTest) {
1406        AThread thr = new AThread();
1407        thr.start();
1408
1409        synchronized (thr) {
1410            while (thr.mService == null) {
1411                try {
1412                    thr.wait();
1413                } catch (InterruptedException e) {
1414                }
1415            }
1416        }
1417
1418        ActivityManagerService m = thr.mService;
1419        mSelf = m;
1420        ActivityThread at = ActivityThread.systemMain();
1421        mSystemThread = at;
1422        Context context = at.getSystemContext();
1423        context.setTheme(android.R.style.Theme_Holo);
1424        m.mContext = context;
1425        m.mFactoryTest = factoryTest;
1426        m.mMainStack = new ActivityStack(m, context, true);
1427
1428        m.mBatteryStatsService.publish(context);
1429        m.mUsageStatsService.publish(context);
1430
1431        synchronized (thr) {
1432            thr.mReady = true;
1433            thr.notifyAll();
1434        }
1435
1436        m.startRunning(null, null, null, null);
1437
1438        return context;
1439    }
1440
1441    public static ActivityManagerService self() {
1442        return mSelf;
1443    }
1444
1445    static class AThread extends Thread {
1446        ActivityManagerService mService;
1447        boolean mReady = false;
1448
1449        public AThread() {
1450            super("ActivityManager");
1451        }
1452
1453        public void run() {
1454            Looper.prepare();
1455
1456            android.os.Process.setThreadPriority(
1457                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1458            android.os.Process.setCanSelfBackground(false);
1459
1460            ActivityManagerService m = new ActivityManagerService();
1461
1462            synchronized (this) {
1463                mService = m;
1464                notifyAll();
1465            }
1466
1467            synchronized (this) {
1468                while (!mReady) {
1469                    try {
1470                        wait();
1471                    } catch (InterruptedException e) {
1472                    }
1473                }
1474            }
1475
1476            // For debug builds, log event loop stalls to dropbox for analysis.
1477            if (StrictMode.conditionallyEnableDebugLogging()) {
1478                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1479            }
1480
1481            Looper.loop();
1482        }
1483    }
1484
1485    static class MemBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        MemBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump meminfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1502                    false, null, null, null);
1503        }
1504    }
1505
1506    static class GraphicsBinder extends Binder {
1507        ActivityManagerService mActivityManagerService;
1508        GraphicsBinder(ActivityManagerService activityManagerService) {
1509            mActivityManagerService = activityManagerService;
1510        }
1511
1512        @Override
1513        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1514            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1515                    != PackageManager.PERMISSION_GRANTED) {
1516                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1517                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1518                        + " without permission " + android.Manifest.permission.DUMP);
1519                return;
1520            }
1521
1522            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1523        }
1524    }
1525
1526    static class DbBinder extends Binder {
1527        ActivityManagerService mActivityManagerService;
1528        DbBinder(ActivityManagerService activityManagerService) {
1529            mActivityManagerService = activityManagerService;
1530        }
1531
1532        @Override
1533        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1534            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1535                    != PackageManager.PERMISSION_GRANTED) {
1536                pw.println("Permission Denial: can't dump dbinfo from from pid="
1537                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1538                        + " without permission " + android.Manifest.permission.DUMP);
1539                return;
1540            }
1541
1542            mActivityManagerService.dumpDbInfo(fd, pw, args);
1543        }
1544    }
1545
1546    static class CpuBinder extends Binder {
1547        ActivityManagerService mActivityManagerService;
1548        CpuBinder(ActivityManagerService activityManagerService) {
1549            mActivityManagerService = activityManagerService;
1550        }
1551
1552        @Override
1553        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1554            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1555                    != PackageManager.PERMISSION_GRANTED) {
1556                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1557                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1558                        + " without permission " + android.Manifest.permission.DUMP);
1559                return;
1560            }
1561
1562            synchronized (mActivityManagerService.mProcessStatsThread) {
1563                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1564                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1565                        SystemClock.uptimeMillis()));
1566            }
1567        }
1568    }
1569
1570    private ActivityManagerService() {
1571        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1572
1573        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1574        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1575        mBroadcastQueues[0] = mFgBroadcastQueue;
1576        mBroadcastQueues[1] = mBgBroadcastQueue;
1577
1578        mServices = new ActiveServices(this);
1579        mProviderMap = new ProviderMap(this);
1580
1581        File dataDir = Environment.getDataDirectory();
1582        File systemDir = new File(dataDir, "system");
1583        systemDir.mkdirs();
1584        mBatteryStatsService = new BatteryStatsService(new File(
1585                systemDir, "batterystats.bin").toString());
1586        mBatteryStatsService.getActiveStatistics().readLocked();
1587        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1588        mOnBattery = DEBUG_POWER ? true
1589                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1590        mBatteryStatsService.getActiveStatistics().setCallback(this);
1591
1592        mUsageStatsService = new UsageStatsService(new File(
1593                systemDir, "usagestats").toString());
1594        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1595
1596        // User 0 is the first and only user that runs at boot.
1597        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1598        mUserLru.add(Integer.valueOf(0));
1599        updateStartedUserArrayLocked();
1600
1601        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1602            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1603
1604        mConfiguration.setToDefaults();
1605        mConfiguration.setLocale(Locale.getDefault());
1606
1607        mConfigurationSeq = mConfiguration.seq = 1;
1608        mProcessStats.init();
1609
1610        mCompatModePackages = new CompatModePackages(this, systemDir);
1611
1612        // Add ourself to the Watchdog monitors.
1613        Watchdog.getInstance().addMonitor(this);
1614
1615        mProcessStatsThread = new Thread("ProcessStats") {
1616            public void run() {
1617                while (true) {
1618                    try {
1619                        try {
1620                            synchronized(this) {
1621                                final long now = SystemClock.uptimeMillis();
1622                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1623                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1624                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1625                                //        + ", write delay=" + nextWriteDelay);
1626                                if (nextWriteDelay < nextCpuDelay) {
1627                                    nextCpuDelay = nextWriteDelay;
1628                                }
1629                                if (nextCpuDelay > 0) {
1630                                    mProcessStatsMutexFree.set(true);
1631                                    this.wait(nextCpuDelay);
1632                                }
1633                            }
1634                        } catch (InterruptedException e) {
1635                        }
1636                        updateCpuStatsNow();
1637                    } catch (Exception e) {
1638                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1639                    }
1640                }
1641            }
1642        };
1643        mProcessStatsThread.start();
1644    }
1645
1646    @Override
1647    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1648            throws RemoteException {
1649        if (code == SYSPROPS_TRANSACTION) {
1650            // We need to tell all apps about the system property change.
1651            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1652            synchronized(this) {
1653                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1654                    final int NA = apps.size();
1655                    for (int ia=0; ia<NA; ia++) {
1656                        ProcessRecord app = apps.valueAt(ia);
1657                        if (app.thread != null) {
1658                            procs.add(app.thread.asBinder());
1659                        }
1660                    }
1661                }
1662            }
1663
1664            int N = procs.size();
1665            for (int i=0; i<N; i++) {
1666                Parcel data2 = Parcel.obtain();
1667                try {
1668                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1669                } catch (RemoteException e) {
1670                }
1671                data2.recycle();
1672            }
1673        }
1674        try {
1675            return super.onTransact(code, data, reply, flags);
1676        } catch (RuntimeException e) {
1677            // The activity manager only throws security exceptions, so let's
1678            // log all others.
1679            if (!(e instanceof SecurityException)) {
1680                Slog.e(TAG, "Activity Manager Crash", e);
1681            }
1682            throw e;
1683        }
1684    }
1685
1686    void updateCpuStats() {
1687        final long now = SystemClock.uptimeMillis();
1688        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1689            return;
1690        }
1691        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1692            synchronized (mProcessStatsThread) {
1693                mProcessStatsThread.notify();
1694            }
1695        }
1696    }
1697
1698    void updateCpuStatsNow() {
1699        synchronized (mProcessStatsThread) {
1700            mProcessStatsMutexFree.set(false);
1701            final long now = SystemClock.uptimeMillis();
1702            boolean haveNewCpuStats = false;
1703
1704            if (MONITOR_CPU_USAGE &&
1705                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1706                mLastCpuTime.set(now);
1707                haveNewCpuStats = true;
1708                mProcessStats.update();
1709                //Slog.i(TAG, mProcessStats.printCurrentState());
1710                //Slog.i(TAG, "Total CPU usage: "
1711                //        + mProcessStats.getTotalCpuPercent() + "%");
1712
1713                // Slog the cpu usage if the property is set.
1714                if ("true".equals(SystemProperties.get("events.cpu"))) {
1715                    int user = mProcessStats.getLastUserTime();
1716                    int system = mProcessStats.getLastSystemTime();
1717                    int iowait = mProcessStats.getLastIoWaitTime();
1718                    int irq = mProcessStats.getLastIrqTime();
1719                    int softIrq = mProcessStats.getLastSoftIrqTime();
1720                    int idle = mProcessStats.getLastIdleTime();
1721
1722                    int total = user + system + iowait + irq + softIrq + idle;
1723                    if (total == 0) total = 1;
1724
1725                    EventLog.writeEvent(EventLogTags.CPU,
1726                            ((user+system+iowait+irq+softIrq) * 100) / total,
1727                            (user * 100) / total,
1728                            (system * 100) / total,
1729                            (iowait * 100) / total,
1730                            (irq * 100) / total,
1731                            (softIrq * 100) / total);
1732                }
1733            }
1734
1735            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1736            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1737            synchronized(bstats) {
1738                synchronized(mPidsSelfLocked) {
1739                    if (haveNewCpuStats) {
1740                        if (mOnBattery) {
1741                            int perc = bstats.startAddingCpuLocked();
1742                            int totalUTime = 0;
1743                            int totalSTime = 0;
1744                            final int N = mProcessStats.countStats();
1745                            for (int i=0; i<N; i++) {
1746                                ProcessStats.Stats st = mProcessStats.getStats(i);
1747                                if (!st.working) {
1748                                    continue;
1749                                }
1750                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1751                                int otherUTime = (st.rel_utime*perc)/100;
1752                                int otherSTime = (st.rel_stime*perc)/100;
1753                                totalUTime += otherUTime;
1754                                totalSTime += otherSTime;
1755                                if (pr != null) {
1756                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1757                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1758                                            st.rel_stime-otherSTime);
1759                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1760                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1761                                } else {
1762                                    BatteryStatsImpl.Uid.Proc ps =
1763                                            bstats.getProcessStatsLocked(st.name, st.pid);
1764                                    if (ps != null) {
1765                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1766                                                st.rel_stime-otherSTime);
1767                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1768                                    }
1769                                }
1770                            }
1771                            bstats.finishAddingCpuLocked(perc, totalUTime,
1772                                    totalSTime, cpuSpeedTimes);
1773                        }
1774                    }
1775                }
1776
1777                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1778                    mLastWriteTime = now;
1779                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1780                }
1781            }
1782        }
1783    }
1784
1785    @Override
1786    public void batteryNeedsCpuUpdate() {
1787        updateCpuStatsNow();
1788    }
1789
1790    @Override
1791    public void batteryPowerChanged(boolean onBattery) {
1792        // When plugging in, update the CPU stats first before changing
1793        // the plug state.
1794        updateCpuStatsNow();
1795        synchronized (this) {
1796            synchronized(mPidsSelfLocked) {
1797                mOnBattery = DEBUG_POWER ? true : onBattery;
1798            }
1799        }
1800    }
1801
1802    /**
1803     * Initialize the application bind args. These are passed to each
1804     * process when the bindApplication() IPC is sent to the process. They're
1805     * lazily setup to make sure the services are running when they're asked for.
1806     */
1807    private HashMap<String, IBinder> getCommonServicesLocked() {
1808        if (mAppBindArgs == null) {
1809            mAppBindArgs = new HashMap<String, IBinder>();
1810
1811            // Setup the application init args
1812            mAppBindArgs.put("package", ServiceManager.getService("package"));
1813            mAppBindArgs.put("window", ServiceManager.getService("window"));
1814            mAppBindArgs.put(Context.ALARM_SERVICE,
1815                    ServiceManager.getService(Context.ALARM_SERVICE));
1816        }
1817        return mAppBindArgs;
1818    }
1819
1820    final void setFocusedActivityLocked(ActivityRecord r) {
1821        if (mFocusedActivity != r) {
1822            mFocusedActivity = r;
1823            if (r != null) {
1824                mWindowManager.setFocusedApp(r.appToken, true);
1825            }
1826        }
1827    }
1828
1829    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1830        // put it on the LRU to keep track of when it should be exited.
1831        int lrui = mLruProcesses.indexOf(app);
1832        if (lrui >= 0) mLruProcesses.remove(lrui);
1833
1834        int i = mLruProcesses.size()-1;
1835        int skipTop = 0;
1836
1837        app.lruSeq = mLruSeq;
1838
1839        // compute the new weight for this process.
1840        app.lastActivityTime = SystemClock.uptimeMillis();
1841        if (app.activities.size() > 0) {
1842            // If this process has activities, we more strongly want to keep
1843            // it around.
1844            app.lruWeight = app.lastActivityTime;
1845        } else if (app.pubProviders.size() > 0) {
1846            // If this process contains content providers, we want to keep
1847            // it a little more strongly.
1848            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1849            // Also don't let it kick out the first few "real" hidden processes.
1850            skipTop = ProcessList.MIN_HIDDEN_APPS;
1851        } else {
1852            // If this process doesn't have activities, we less strongly
1853            // want to keep it around, and generally want to avoid getting
1854            // in front of any very recently used activities.
1855            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1856            // Also don't let it kick out the first few "real" hidden processes.
1857            skipTop = ProcessList.MIN_HIDDEN_APPS;
1858        }
1859
1860        while (i >= 0) {
1861            ProcessRecord p = mLruProcesses.get(i);
1862            // If this app shouldn't be in front of the first N background
1863            // apps, then skip over that many that are currently hidden.
1864            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1865                skipTop--;
1866            }
1867            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1868                mLruProcesses.add(i+1, app);
1869                break;
1870            }
1871            i--;
1872        }
1873        if (i < 0) {
1874            mLruProcesses.add(0, app);
1875        }
1876
1877        // If the app is currently using a content provider or service,
1878        // bump those processes as well.
1879        if (app.connections.size() > 0) {
1880            for (ConnectionRecord cr : app.connections) {
1881                if (cr.binding != null && cr.binding.service != null
1882                        && cr.binding.service.app != null
1883                        && cr.binding.service.app.lruSeq != mLruSeq) {
1884                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1885                }
1886            }
1887        }
1888        for (int j=app.conProviders.size()-1; j>=0; j--) {
1889            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1890            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1891                updateLruProcessInternalLocked(cpr.proc, i+1);
1892            }
1893        }
1894    }
1895
1896    final void updateLruProcessLocked(ProcessRecord app,
1897            boolean oomAdj) {
1898        mLruSeq++;
1899        updateLruProcessInternalLocked(app, 0);
1900
1901        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1902        if (oomAdj) {
1903            updateOomAdjLocked();
1904        }
1905    }
1906
1907    final ProcessRecord getProcessRecordLocked(
1908            String processName, int uid) {
1909        if (uid == Process.SYSTEM_UID) {
1910            // The system gets to run in any process.  If there are multiple
1911            // processes with the same uid, just pick the first (this
1912            // should never happen).
1913            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1914                    processName);
1915            if (procs == null) return null;
1916            final int N = procs.size();
1917            for (int i = 0; i < N; i++) {
1918                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1919            }
1920        }
1921        ProcessRecord proc = mProcessNames.get(processName, uid);
1922        return proc;
1923    }
1924
1925    void ensurePackageDexOpt(String packageName) {
1926        IPackageManager pm = AppGlobals.getPackageManager();
1927        try {
1928            if (pm.performDexOpt(packageName)) {
1929                mDidDexOpt = true;
1930            }
1931        } catch (RemoteException e) {
1932        }
1933    }
1934
1935    boolean isNextTransitionForward() {
1936        int transit = mWindowManager.getPendingAppTransition();
1937        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1938                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1939                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1940    }
1941
1942    final ProcessRecord startProcessLocked(String processName,
1943            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1944            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1945            boolean isolated) {
1946        ProcessRecord app;
1947        if (!isolated) {
1948            app = getProcessRecordLocked(processName, info.uid);
1949        } else {
1950            // If this is an isolated process, it can't re-use an existing process.
1951            app = null;
1952        }
1953        // We don't have to do anything more if:
1954        // (1) There is an existing application record; and
1955        // (2) The caller doesn't think it is dead, OR there is no thread
1956        //     object attached to it so we know it couldn't have crashed; and
1957        // (3) There is a pid assigned to it, so it is either starting or
1958        //     already running.
1959        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1960                + " app=" + app + " knownToBeDead=" + knownToBeDead
1961                + " thread=" + (app != null ? app.thread : null)
1962                + " pid=" + (app != null ? app.pid : -1));
1963        if (app != null && app.pid > 0) {
1964            if (!knownToBeDead || app.thread == null) {
1965                // We already have the app running, or are waiting for it to
1966                // come up (we have a pid but not yet its thread), so keep it.
1967                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1968                // If this is a new package in the process, add the package to the list
1969                app.addPackage(info.packageName);
1970                return app;
1971            } else {
1972                // An application record is attached to a previous process,
1973                // clean it up now.
1974                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
1975                handleAppDiedLocked(app, true, true);
1976            }
1977        }
1978
1979        String hostingNameStr = hostingName != null
1980                ? hostingName.flattenToShortString() : null;
1981
1982        if (!isolated) {
1983            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1984                // If we are in the background, then check to see if this process
1985                // is bad.  If so, we will just silently fail.
1986                if (mBadProcesses.get(info.processName, info.uid) != null) {
1987                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1988                            + "/" + info.processName);
1989                    return null;
1990                }
1991            } else {
1992                // When the user is explicitly starting a process, then clear its
1993                // crash count so that we won't make it bad until they see at
1994                // least one crash dialog again, and make the process good again
1995                // if it had been bad.
1996                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1997                        + "/" + info.processName);
1998                mProcessCrashTimes.remove(info.processName, info.uid);
1999                if (mBadProcesses.get(info.processName, info.uid) != null) {
2000                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2001                            UserHandle.getUserId(info.uid), info.uid,
2002                            info.processName);
2003                    mBadProcesses.remove(info.processName, info.uid);
2004                    if (app != null) {
2005                        app.bad = false;
2006                    }
2007                }
2008            }
2009        }
2010
2011        if (app == null) {
2012            app = newProcessRecordLocked(null, info, processName, isolated);
2013            if (app == null) {
2014                Slog.w(TAG, "Failed making new process record for "
2015                        + processName + "/" + info.uid + " isolated=" + isolated);
2016                return null;
2017            }
2018            mProcessNames.put(processName, app.uid, app);
2019            if (isolated) {
2020                mIsolatedProcesses.put(app.uid, app);
2021            }
2022        } else {
2023            // If this is a new package in the process, add the package to the list
2024            app.addPackage(info.packageName);
2025        }
2026
2027        // If the system is not ready yet, then hold off on starting this
2028        // process until it is.
2029        if (!mProcessesReady
2030                && !isAllowedWhileBooting(info)
2031                && !allowWhileBooting) {
2032            if (!mProcessesOnHold.contains(app)) {
2033                mProcessesOnHold.add(app);
2034            }
2035            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2036            return app;
2037        }
2038
2039        startProcessLocked(app, hostingType, hostingNameStr);
2040        return (app.pid != 0) ? app : null;
2041    }
2042
2043    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2044        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2045    }
2046
2047    private final void startProcessLocked(ProcessRecord app,
2048            String hostingType, String hostingNameStr) {
2049        if (app.pid > 0 && app.pid != MY_PID) {
2050            synchronized (mPidsSelfLocked) {
2051                mPidsSelfLocked.remove(app.pid);
2052                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2053            }
2054            app.setPid(0);
2055        }
2056
2057        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2058                "startProcessLocked removing on hold: " + app);
2059        mProcessesOnHold.remove(app);
2060
2061        updateCpuStats();
2062
2063        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2064        mProcDeaths[0] = 0;
2065
2066        try {
2067            int uid = app.uid;
2068
2069            int[] gids = null;
2070            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2071            if (!app.isolated) {
2072                int[] permGids = null;
2073                try {
2074                    final PackageManager pm = mContext.getPackageManager();
2075                    permGids = pm.getPackageGids(app.info.packageName);
2076
2077                    if (Environment.isExternalStorageEmulated()) {
2078                        if (pm.checkPermission(
2079                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2080                                app.info.packageName) == PERMISSION_GRANTED) {
2081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2082                        } else {
2083                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2084                        }
2085                    }
2086                } catch (PackageManager.NameNotFoundException e) {
2087                    Slog.w(TAG, "Unable to retrieve gids", e);
2088                }
2089
2090                /*
2091                 * Add shared application GID so applications can share some
2092                 * resources like shared libraries
2093                 */
2094                if (permGids == null) {
2095                    gids = new int[1];
2096                } else {
2097                    gids = new int[permGids.length + 1];
2098                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2099                }
2100                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2101            }
2102            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2103                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2104                        && mTopComponent != null
2105                        && app.processName.equals(mTopComponent.getPackageName())) {
2106                    uid = 0;
2107                }
2108                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2109                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2110                    uid = 0;
2111                }
2112            }
2113            int debugFlags = 0;
2114            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2115                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2116                // Also turn on CheckJNI for debuggable apps. It's quite
2117                // awkward to turn on otherwise.
2118                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2119            }
2120            // Run the app in safe mode if its manifest requests so or the
2121            // system is booted in safe mode.
2122            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2123                Zygote.systemInSafeMode == true) {
2124                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2125            }
2126            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2127                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2128            }
2129            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2130                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2131            }
2132            if ("1".equals(SystemProperties.get("debug.assert"))) {
2133                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2134            }
2135
2136            // Start the process.  It will either succeed and return a result containing
2137            // the PID of the new process, or else throw a RuntimeException.
2138            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2139                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2140                    app.info.targetSdkVersion, null, null);
2141
2142            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2143            synchronized (bs) {
2144                if (bs.isOnBattery()) {
2145                    app.batteryStats.incStartsLocked();
2146                }
2147            }
2148
2149            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2150                    UserHandle.getUserId(uid), startResult.pid, uid,
2151                    app.processName, hostingType,
2152                    hostingNameStr != null ? hostingNameStr : "");
2153
2154            if (app.persistent) {
2155                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2156            }
2157
2158            StringBuilder buf = mStringBuilder;
2159            buf.setLength(0);
2160            buf.append("Start proc ");
2161            buf.append(app.processName);
2162            buf.append(" for ");
2163            buf.append(hostingType);
2164            if (hostingNameStr != null) {
2165                buf.append(" ");
2166                buf.append(hostingNameStr);
2167            }
2168            buf.append(": pid=");
2169            buf.append(startResult.pid);
2170            buf.append(" uid=");
2171            buf.append(uid);
2172            buf.append(" gids={");
2173            if (gids != null) {
2174                for (int gi=0; gi<gids.length; gi++) {
2175                    if (gi != 0) buf.append(", ");
2176                    buf.append(gids[gi]);
2177
2178                }
2179            }
2180            buf.append("}");
2181            Slog.i(TAG, buf.toString());
2182            app.setPid(startResult.pid);
2183            app.usingWrapper = startResult.usingWrapper;
2184            app.removed = false;
2185            synchronized (mPidsSelfLocked) {
2186                this.mPidsSelfLocked.put(startResult.pid, app);
2187                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2188                msg.obj = app;
2189                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2190                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2191            }
2192        } catch (RuntimeException e) {
2193            // XXX do better error recovery.
2194            app.setPid(0);
2195            Slog.e(TAG, "Failure starting process " + app.processName, e);
2196        }
2197    }
2198
2199    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2200        if (resumed) {
2201            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2202        } else {
2203            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2204        }
2205    }
2206
2207    boolean startHomeActivityLocked(int userId) {
2208        if (mHeadless) {
2209            // Added because none of the other calls to ensureBootCompleted seem to fire
2210            // when running headless.
2211            ensureBootCompleted();
2212            return false;
2213        }
2214
2215        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2216                && mTopAction == null) {
2217            // We are running in factory test mode, but unable to find
2218            // the factory test app, so just sit around displaying the
2219            // error message and don't try to start anything.
2220            return false;
2221        }
2222        Intent intent = new Intent(
2223            mTopAction,
2224            mTopData != null ? Uri.parse(mTopData) : null);
2225        intent.setComponent(mTopComponent);
2226        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2227            intent.addCategory(Intent.CATEGORY_HOME);
2228        }
2229        ActivityInfo aInfo =
2230            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2231        if (aInfo != null) {
2232            intent.setComponent(new ComponentName(
2233                    aInfo.applicationInfo.packageName, aInfo.name));
2234            // Don't do this if the home app is currently being
2235            // instrumented.
2236            aInfo = new ActivityInfo(aInfo);
2237            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2238            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2239                    aInfo.applicationInfo.uid);
2240            if (app == null || app.instrumentationClass == null) {
2241                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2242                mMainStack.startActivityLocked(null, intent, null, aInfo,
2243                        null, null, 0, 0, 0, 0, null, false, null);
2244            }
2245        }
2246
2247        return true;
2248    }
2249
2250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2251        ActivityInfo ai = null;
2252        ComponentName comp = intent.getComponent();
2253        try {
2254            if (comp != null) {
2255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2256            } else {
2257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2258                        intent,
2259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2260                            flags, userId);
2261
2262                if (info != null) {
2263                    ai = info.activityInfo;
2264                }
2265            }
2266        } catch (RemoteException e) {
2267            // ignore
2268        }
2269
2270        return ai;
2271    }
2272
2273    /**
2274     * Starts the "new version setup screen" if appropriate.
2275     */
2276    void startSetupActivityLocked() {
2277        // Only do this once per boot.
2278        if (mCheckedForSetup) {
2279            return;
2280        }
2281
2282        // We will show this screen if the current one is a different
2283        // version than the last one shown, and we are not running in
2284        // low-level factory test mode.
2285        final ContentResolver resolver = mContext.getContentResolver();
2286        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2287                Settings.Global.getInt(resolver,
2288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2289            mCheckedForSetup = true;
2290
2291            // See if we should be showing the platform update setup UI.
2292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2293            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2295
2296            // We don't allow third party apps to replace this.
2297            ResolveInfo ri = null;
2298            for (int i=0; ris != null && i<ris.size(); i++) {
2299                if ((ris.get(i).activityInfo.applicationInfo.flags
2300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2301                    ri = ris.get(i);
2302                    break;
2303                }
2304            }
2305
2306            if (ri != null) {
2307                String vers = ri.activityInfo.metaData != null
2308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2309                        : null;
2310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2312                            Intent.METADATA_SETUP_VERSION);
2313                }
2314                String lastVers = Settings.Secure.getString(
2315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2316                if (vers != null && !vers.equals(lastVers)) {
2317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2318                    intent.setComponent(new ComponentName(
2319                            ri.activityInfo.packageName, ri.activityInfo.name));
2320                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2321                            null, null, 0, 0, 0, 0, null, false, null);
2322                }
2323            }
2324        }
2325    }
2326
2327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2329    }
2330
2331    void enforceNotIsolatedCaller(String caller) {
2332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2333            throw new SecurityException("Isolated process not allowed to call " + caller);
2334        }
2335    }
2336
2337    public int getFrontActivityScreenCompatMode() {
2338        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2339        synchronized (this) {
2340            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2341        }
2342    }
2343
2344    public void setFrontActivityScreenCompatMode(int mode) {
2345        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2346                "setFrontActivityScreenCompatMode");
2347        synchronized (this) {
2348            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2349        }
2350    }
2351
2352    public int getPackageScreenCompatMode(String packageName) {
2353        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2354        synchronized (this) {
2355            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2356        }
2357    }
2358
2359    public void setPackageScreenCompatMode(String packageName, int mode) {
2360        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2361                "setPackageScreenCompatMode");
2362        synchronized (this) {
2363            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2364        }
2365    }
2366
2367    public boolean getPackageAskScreenCompat(String packageName) {
2368        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2369        synchronized (this) {
2370            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2371        }
2372    }
2373
2374    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2376                "setPackageAskScreenCompat");
2377        synchronized (this) {
2378            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2379        }
2380    }
2381
2382    void reportResumedActivityLocked(ActivityRecord r) {
2383        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2384        updateUsageStats(r, true);
2385    }
2386
2387    private void dispatchProcessesChanged() {
2388        int N;
2389        synchronized (this) {
2390            N = mPendingProcessChanges.size();
2391            if (mActiveProcessChanges.length < N) {
2392                mActiveProcessChanges = new ProcessChangeItem[N];
2393            }
2394            mPendingProcessChanges.toArray(mActiveProcessChanges);
2395            mAvailProcessChanges.addAll(mPendingProcessChanges);
2396            mPendingProcessChanges.clear();
2397            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2398        }
2399        int i = mProcessObservers.beginBroadcast();
2400        while (i > 0) {
2401            i--;
2402            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2403            if (observer != null) {
2404                try {
2405                    for (int j=0; j<N; j++) {
2406                        ProcessChangeItem item = mActiveProcessChanges[j];
2407                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2408                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2409                                    + item.pid + " uid=" + item.uid + ": "
2410                                    + item.foregroundActivities);
2411                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2412                                    item.foregroundActivities);
2413                        }
2414                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2415                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2416                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2417                            observer.onImportanceChanged(item.pid, item.uid,
2418                                    item.importance);
2419                        }
2420                    }
2421                } catch (RemoteException e) {
2422                }
2423            }
2424        }
2425        mProcessObservers.finishBroadcast();
2426    }
2427
2428    private void dispatchProcessDied(int pid, int uid) {
2429        int i = mProcessObservers.beginBroadcast();
2430        while (i > 0) {
2431            i--;
2432            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2433            if (observer != null) {
2434                try {
2435                    observer.onProcessDied(pid, uid);
2436                } catch (RemoteException e) {
2437                }
2438            }
2439        }
2440        mProcessObservers.finishBroadcast();
2441    }
2442
2443    final void doPendingActivityLaunchesLocked(boolean doResume) {
2444        final int N = mPendingActivityLaunches.size();
2445        if (N <= 0) {
2446            return;
2447        }
2448        for (int i=0; i<N; i++) {
2449            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2450            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2451                    pal.startFlags, doResume && i == (N-1), null);
2452        }
2453        mPendingActivityLaunches.clear();
2454    }
2455
2456    public final int startActivity(IApplicationThread caller,
2457            Intent intent, String resolvedType, IBinder resultTo,
2458            String resultWho, int requestCode, int startFlags,
2459            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2460        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2461                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2462    }
2463
2464    public final int startActivityAsUser(IApplicationThread caller,
2465            Intent intent, String resolvedType, IBinder resultTo,
2466            String resultWho, int requestCode, int startFlags,
2467            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2468        enforceNotIsolatedCaller("startActivity");
2469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2470                false, true, "startActivity", null);
2471        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2472                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2473                null, null, options, userId);
2474    }
2475
2476    public final WaitResult startActivityAndWait(IApplicationThread caller,
2477            Intent intent, String resolvedType, IBinder resultTo,
2478            String resultWho, int requestCode, int startFlags, String profileFile,
2479            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2480        enforceNotIsolatedCaller("startActivityAndWait");
2481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2482                false, true, "startActivityAndWait", null);
2483        WaitResult res = new WaitResult();
2484        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2485                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2486                res, null, options, UserHandle.getCallingUserId());
2487        return res;
2488    }
2489
2490    public final int startActivityWithConfig(IApplicationThread caller,
2491            Intent intent, String resolvedType, IBinder resultTo,
2492            String resultWho, int requestCode, int startFlags, Configuration config,
2493            Bundle options, int userId) {
2494        enforceNotIsolatedCaller("startActivityWithConfig");
2495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2496                false, true, "startActivityWithConfig", null);
2497        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2498                resultTo, resultWho, requestCode, startFlags,
2499                null, null, null, config, options, userId);
2500        return ret;
2501    }
2502
2503    public int startActivityIntentSender(IApplicationThread caller,
2504            IntentSender intent, Intent fillInIntent, String resolvedType,
2505            IBinder resultTo, String resultWho, int requestCode,
2506            int flagsMask, int flagsValues, Bundle options) {
2507        enforceNotIsolatedCaller("startActivityIntentSender");
2508        // Refuse possible leaked file descriptors
2509        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2510            throw new IllegalArgumentException("File descriptors passed in Intent");
2511        }
2512
2513        IIntentSender sender = intent.getTarget();
2514        if (!(sender instanceof PendingIntentRecord)) {
2515            throw new IllegalArgumentException("Bad PendingIntent object");
2516        }
2517
2518        PendingIntentRecord pir = (PendingIntentRecord)sender;
2519
2520        synchronized (this) {
2521            // If this is coming from the currently resumed activity, it is
2522            // effectively saying that app switches are allowed at this point.
2523            if (mMainStack.mResumedActivity != null
2524                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2525                            Binder.getCallingUid()) {
2526                mAppSwitchesAllowedTime = 0;
2527            }
2528        }
2529        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2530                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2531        return ret;
2532    }
2533
2534    public boolean startNextMatchingActivity(IBinder callingActivity,
2535            Intent intent, Bundle options) {
2536        // Refuse possible leaked file descriptors
2537        if (intent != null && intent.hasFileDescriptors() == true) {
2538            throw new IllegalArgumentException("File descriptors passed in Intent");
2539        }
2540
2541        synchronized (this) {
2542            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2543            if (r == null) {
2544                ActivityOptions.abort(options);
2545                return false;
2546            }
2547            if (r.app == null || r.app.thread == null) {
2548                // The caller is not running...  d'oh!
2549                ActivityOptions.abort(options);
2550                return false;
2551            }
2552            intent = new Intent(intent);
2553            // The caller is not allowed to change the data.
2554            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2555            // And we are resetting to find the next component...
2556            intent.setComponent(null);
2557
2558            ActivityInfo aInfo = null;
2559            try {
2560                List<ResolveInfo> resolves =
2561                    AppGlobals.getPackageManager().queryIntentActivities(
2562                            intent, r.resolvedType,
2563                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2564                            UserHandle.getCallingUserId());
2565
2566                // Look for the original activity in the list...
2567                final int N = resolves != null ? resolves.size() : 0;
2568                for (int i=0; i<N; i++) {
2569                    ResolveInfo rInfo = resolves.get(i);
2570                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2571                            && rInfo.activityInfo.name.equals(r.info.name)) {
2572                        // We found the current one...  the next matching is
2573                        // after it.
2574                        i++;
2575                        if (i<N) {
2576                            aInfo = resolves.get(i).activityInfo;
2577                        }
2578                        break;
2579                    }
2580                }
2581            } catch (RemoteException e) {
2582            }
2583
2584            if (aInfo == null) {
2585                // Nobody who is next!
2586                ActivityOptions.abort(options);
2587                return false;
2588            }
2589
2590            intent.setComponent(new ComponentName(
2591                    aInfo.applicationInfo.packageName, aInfo.name));
2592            intent.setFlags(intent.getFlags()&~(
2593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2596                    Intent.FLAG_ACTIVITY_NEW_TASK));
2597
2598            // Okay now we need to start the new activity, replacing the
2599            // currently running activity.  This is a little tricky because
2600            // we want to start the new one as if the current one is finished,
2601            // but not finish the current one first so that there is no flicker.
2602            // And thus...
2603            final boolean wasFinishing = r.finishing;
2604            r.finishing = true;
2605
2606            // Propagate reply information over to the new activity.
2607            final ActivityRecord resultTo = r.resultTo;
2608            final String resultWho = r.resultWho;
2609            final int requestCode = r.requestCode;
2610            r.resultTo = null;
2611            if (resultTo != null) {
2612                resultTo.removeResultsLocked(r, resultWho, requestCode);
2613            }
2614
2615            final long origId = Binder.clearCallingIdentity();
2616            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2617                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2618                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2619                    options, false, null);
2620            Binder.restoreCallingIdentity(origId);
2621
2622            r.finishing = wasFinishing;
2623            if (res != ActivityManager.START_SUCCESS) {
2624                return false;
2625            }
2626            return true;
2627        }
2628    }
2629
2630    final int startActivityInPackage(int uid,
2631            Intent intent, String resolvedType, IBinder resultTo,
2632            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2633
2634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2635                false, true, "startActivityInPackage", null);
2636
2637        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2638                resultTo, resultWho, requestCode, startFlags,
2639                null, null, null, null, options, userId);
2640        return ret;
2641    }
2642
2643    public final int startActivities(IApplicationThread caller,
2644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2645            int userId) {
2646        enforceNotIsolatedCaller("startActivities");
2647        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2648                false, true, "startActivity", null);
2649        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2650                options, userId);
2651        return ret;
2652    }
2653
2654    final int startActivitiesInPackage(int uid,
2655            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2656            Bundle options, int userId) {
2657
2658        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2659                false, true, "startActivityInPackage", null);
2660        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2661                options, userId);
2662        return ret;
2663    }
2664
2665    final void addRecentTaskLocked(TaskRecord task) {
2666        int N = mRecentTasks.size();
2667        // Quick case: check if the top-most recent task is the same.
2668        if (N > 0 && mRecentTasks.get(0) == task) {
2669            return;
2670        }
2671        // Remove any existing entries that are the same kind of task.
2672        for (int i=0; i<N; i++) {
2673            TaskRecord tr = mRecentTasks.get(i);
2674            if (task.userId == tr.userId
2675                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2676                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2677                mRecentTasks.remove(i);
2678                i--;
2679                N--;
2680                if (task.intent == null) {
2681                    // If the new recent task we are adding is not fully
2682                    // specified, then replace it with the existing recent task.
2683                    task = tr;
2684                }
2685            }
2686        }
2687        if (N >= MAX_RECENT_TASKS) {
2688            mRecentTasks.remove(N-1);
2689        }
2690        mRecentTasks.add(0, task);
2691    }
2692
2693    public void setRequestedOrientation(IBinder token,
2694            int requestedOrientation) {
2695        synchronized (this) {
2696            ActivityRecord r = mMainStack.isInStackLocked(token);
2697            if (r == null) {
2698                return;
2699            }
2700            final long origId = Binder.clearCallingIdentity();
2701            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2702            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2703                    mConfiguration,
2704                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2705            if (config != null) {
2706                r.frozenBeforeDestroy = true;
2707                if (!updateConfigurationLocked(config, r, false, false)) {
2708                    mMainStack.resumeTopActivityLocked(null);
2709                }
2710            }
2711            Binder.restoreCallingIdentity(origId);
2712        }
2713    }
2714
2715    public int getRequestedOrientation(IBinder token) {
2716        synchronized (this) {
2717            ActivityRecord r = mMainStack.isInStackLocked(token);
2718            if (r == null) {
2719                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2720            }
2721            return mWindowManager.getAppOrientation(r.appToken);
2722        }
2723    }
2724
2725    /**
2726     * This is the internal entry point for handling Activity.finish().
2727     *
2728     * @param token The Binder token referencing the Activity we want to finish.
2729     * @param resultCode Result code, if any, from this Activity.
2730     * @param resultData Result data (Intent), if any, from this Activity.
2731     *
2732     * @return Returns true if the activity successfully finished, or false if it is still running.
2733     */
2734    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2735        // Refuse possible leaked file descriptors
2736        if (resultData != null && resultData.hasFileDescriptors() == true) {
2737            throw new IllegalArgumentException("File descriptors passed in Intent");
2738        }
2739
2740        synchronized(this) {
2741            if (mController != null) {
2742                // Find the first activity that is not finishing.
2743                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2744                if (next != null) {
2745                    // ask watcher if this is allowed
2746                    boolean resumeOK = true;
2747                    try {
2748                        resumeOK = mController.activityResuming(next.packageName);
2749                    } catch (RemoteException e) {
2750                        mController = null;
2751                    }
2752
2753                    if (!resumeOK) {
2754                        return false;
2755                    }
2756                }
2757            }
2758            final long origId = Binder.clearCallingIdentity();
2759            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2760                    resultData, "app-request", true);
2761            Binder.restoreCallingIdentity(origId);
2762            return res;
2763        }
2764    }
2765
2766    public final void finishHeavyWeightApp() {
2767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2768                != PackageManager.PERMISSION_GRANTED) {
2769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2770                    + Binder.getCallingPid()
2771                    + ", uid=" + Binder.getCallingUid()
2772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2773            Slog.w(TAG, msg);
2774            throw new SecurityException(msg);
2775        }
2776
2777        synchronized(this) {
2778            if (mHeavyWeightProcess == null) {
2779                return;
2780            }
2781
2782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2783                    mHeavyWeightProcess.activities);
2784            for (int i=0; i<activities.size(); i++) {
2785                ActivityRecord r = activities.get(i);
2786                if (!r.finishing) {
2787                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2788                    if (index >= 0) {
2789                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2790                                null, "finish-heavy", true);
2791                    }
2792                }
2793            }
2794
2795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2796                    mHeavyWeightProcess.userId, 0));
2797            mHeavyWeightProcess = null;
2798        }
2799    }
2800
2801    public void crashApplication(int uid, int initialPid, String packageName,
2802            String message) {
2803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2804                != PackageManager.PERMISSION_GRANTED) {
2805            String msg = "Permission Denial: crashApplication() from pid="
2806                    + Binder.getCallingPid()
2807                    + ", uid=" + Binder.getCallingUid()
2808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2809            Slog.w(TAG, msg);
2810            throw new SecurityException(msg);
2811        }
2812
2813        synchronized(this) {
2814            ProcessRecord proc = null;
2815
2816            // Figure out which process to kill.  We don't trust that initialPid
2817            // still has any relation to current pids, so must scan through the
2818            // list.
2819            synchronized (mPidsSelfLocked) {
2820                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2821                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2822                    if (p.uid != uid) {
2823                        continue;
2824                    }
2825                    if (p.pid == initialPid) {
2826                        proc = p;
2827                        break;
2828                    }
2829                    for (String str : p.pkgList) {
2830                        if (str.equals(packageName)) {
2831                            proc = p;
2832                        }
2833                    }
2834                }
2835            }
2836
2837            if (proc == null) {
2838                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2839                        + " initialPid=" + initialPid
2840                        + " packageName=" + packageName);
2841                return;
2842            }
2843
2844            if (proc.thread != null) {
2845                if (proc.pid == Process.myPid()) {
2846                    Log.w(TAG, "crashApplication: trying to crash self!");
2847                    return;
2848                }
2849                long ident = Binder.clearCallingIdentity();
2850                try {
2851                    proc.thread.scheduleCrash(message);
2852                } catch (RemoteException e) {
2853                }
2854                Binder.restoreCallingIdentity(ident);
2855            }
2856        }
2857    }
2858
2859    public final void finishSubActivity(IBinder token, String resultWho,
2860            int requestCode) {
2861        synchronized(this) {
2862            final long origId = Binder.clearCallingIdentity();
2863            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2864            Binder.restoreCallingIdentity(origId);
2865        }
2866    }
2867
2868    public boolean finishActivityAffinity(IBinder token) {
2869        synchronized(this) {
2870            final long origId = Binder.clearCallingIdentity();
2871            boolean res = mMainStack.finishActivityAffinityLocked(token);
2872            Binder.restoreCallingIdentity(origId);
2873            return res;
2874        }
2875    }
2876
2877    public boolean willActivityBeVisible(IBinder token) {
2878        synchronized(this) {
2879            int i;
2880            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2881                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2882                if (r.appToken == token) {
2883                    return true;
2884                }
2885                if (r.fullscreen && !r.finishing) {
2886                    return false;
2887                }
2888            }
2889            return true;
2890        }
2891    }
2892
2893    public void overridePendingTransition(IBinder token, String packageName,
2894            int enterAnim, int exitAnim) {
2895        synchronized(this) {
2896            ActivityRecord self = mMainStack.isInStackLocked(token);
2897            if (self == null) {
2898                return;
2899            }
2900
2901            final long origId = Binder.clearCallingIdentity();
2902
2903            if (self.state == ActivityState.RESUMED
2904                    || self.state == ActivityState.PAUSING) {
2905                mWindowManager.overridePendingAppTransition(packageName,
2906                        enterAnim, exitAnim, null);
2907            }
2908
2909            Binder.restoreCallingIdentity(origId);
2910        }
2911    }
2912
2913    /**
2914     * Main function for removing an existing process from the activity manager
2915     * as a result of that process going away.  Clears out all connections
2916     * to the process.
2917     */
2918    private final void handleAppDiedLocked(ProcessRecord app,
2919            boolean restarting, boolean allowRestart) {
2920        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2921        if (!restarting) {
2922            mLruProcesses.remove(app);
2923        }
2924
2925        if (mProfileProc == app) {
2926            clearProfilerLocked();
2927        }
2928
2929        // Just in case...
2930        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2931            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2932                    "App died while pausing: " + mMainStack.mPausingActivity);
2933            mMainStack.mPausingActivity = null;
2934        }
2935        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2936            mMainStack.mLastPausedActivity = null;
2937        }
2938
2939        // Remove this application's activities from active lists.
2940        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2941
2942        app.activities.clear();
2943
2944        if (app.instrumentationClass != null) {
2945            Slog.w(TAG, "Crash of app " + app.processName
2946                  + " running instrumentation " + app.instrumentationClass);
2947            Bundle info = new Bundle();
2948            info.putString("shortMsg", "Process crashed.");
2949            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2950        }
2951
2952        if (!restarting) {
2953            if (!mMainStack.resumeTopActivityLocked(null)) {
2954                // If there was nothing to resume, and we are not already
2955                // restarting this process, but there is a visible activity that
2956                // is hosted by the process...  then make sure all visible
2957                // activities are running, taking care of restarting this
2958                // process.
2959                if (hasVisibleActivities) {
2960                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2961                }
2962            }
2963        }
2964    }
2965
2966    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2967        IBinder threadBinder = thread.asBinder();
2968        // Find the application record.
2969        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2970            ProcessRecord rec = mLruProcesses.get(i);
2971            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2972                return i;
2973            }
2974        }
2975        return -1;
2976    }
2977
2978    final ProcessRecord getRecordForAppLocked(
2979            IApplicationThread thread) {
2980        if (thread == null) {
2981            return null;
2982        }
2983
2984        int appIndex = getLRURecordIndexForAppLocked(thread);
2985        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2986    }
2987
2988    final void appDiedLocked(ProcessRecord app, int pid,
2989            IApplicationThread thread) {
2990
2991        mProcDeaths[0]++;
2992
2993        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2994        synchronized (stats) {
2995            stats.noteProcessDiedLocked(app.info.uid, pid);
2996        }
2997
2998        // Clean up already done if the process has been re-started.
2999        if (app.pid == pid && app.thread != null &&
3000                app.thread.asBinder() == thread.asBinder()) {
3001            if (!app.killedBackground) {
3002                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3003                        + ") has died.");
3004            }
3005            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3006            if (DEBUG_CLEANUP) Slog.v(
3007                TAG, "Dying app: " + app + ", pid: " + pid
3008                + ", thread: " + thread.asBinder());
3009            boolean doLowMem = app.instrumentationClass == null;
3010            handleAppDiedLocked(app, false, true);
3011
3012            if (doLowMem) {
3013                // If there are no longer any background processes running,
3014                // and the app that died was not running instrumentation,
3015                // then tell everyone we are now low on memory.
3016                boolean haveBg = false;
3017                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3018                    ProcessRecord rec = mLruProcesses.get(i);
3019                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3020                        haveBg = true;
3021                        break;
3022                    }
3023                }
3024
3025                if (!haveBg) {
3026                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3027                    long now = SystemClock.uptimeMillis();
3028                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3029                        ProcessRecord rec = mLruProcesses.get(i);
3030                        if (rec != app && rec.thread != null &&
3031                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3032                            // The low memory report is overriding any current
3033                            // state for a GC request.  Make sure to do
3034                            // heavy/important/visible/foreground processes first.
3035                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3036                                rec.lastRequestedGc = 0;
3037                            } else {
3038                                rec.lastRequestedGc = rec.lastLowMemory;
3039                            }
3040                            rec.reportLowMemory = true;
3041                            rec.lastLowMemory = now;
3042                            mProcessesToGc.remove(rec);
3043                            addProcessToGcListLocked(rec);
3044                        }
3045                    }
3046                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3047                    scheduleAppGcsLocked();
3048                }
3049            }
3050        } else if (app.pid != pid) {
3051            // A new process has already been started.
3052            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3053                    + ") has died and restarted (pid " + app.pid + ").");
3054            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3055        } else if (DEBUG_PROCESSES) {
3056            Slog.d(TAG, "Received spurious death notification for thread "
3057                    + thread.asBinder());
3058        }
3059    }
3060
3061    /**
3062     * If a stack trace dump file is configured, dump process stack traces.
3063     * @param clearTraces causes the dump file to be erased prior to the new
3064     *    traces being written, if true; when false, the new traces will be
3065     *    appended to any existing file content.
3066     * @param firstPids of dalvik VM processes to dump stack traces for first
3067     * @param lastPids of dalvik VM processes to dump stack traces for last
3068     * @param nativeProcs optional list of native process names to dump stack crawls
3069     * @return file containing stack traces, or null if no dump file is configured
3070     */
3071    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3072            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3073        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3074        if (tracesPath == null || tracesPath.length() == 0) {
3075            return null;
3076        }
3077
3078        File tracesFile = new File(tracesPath);
3079        try {
3080            File tracesDir = tracesFile.getParentFile();
3081            if (!tracesDir.exists()) {
3082                tracesFile.mkdirs();
3083                if (!SELinux.restorecon(tracesDir)) {
3084                    return null;
3085                }
3086            }
3087            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3088
3089            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3090            tracesFile.createNewFile();
3091            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3092        } catch (IOException e) {
3093            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3094            return null;
3095        }
3096
3097        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3098        return tracesFile;
3099    }
3100
3101    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3102            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3103        // Use a FileObserver to detect when traces finish writing.
3104        // The order of traces is considered important to maintain for legibility.
3105        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3106            public synchronized void onEvent(int event, String path) { notify(); }
3107        };
3108
3109        try {
3110            observer.startWatching();
3111
3112            // First collect all of the stacks of the most important pids.
3113            if (firstPids != null) {
3114                try {
3115                    int num = firstPids.size();
3116                    for (int i = 0; i < num; i++) {
3117                        synchronized (observer) {
3118                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3119                            observer.wait(200);  // Wait for write-close, give up after 200msec
3120                        }
3121                    }
3122                } catch (InterruptedException e) {
3123                    Log.wtf(TAG, e);
3124                }
3125            }
3126
3127            // Next measure CPU usage.
3128            if (processStats != null) {
3129                processStats.init();
3130                System.gc();
3131                processStats.update();
3132                try {
3133                    synchronized (processStats) {
3134                        processStats.wait(500); // measure over 1/2 second.
3135                    }
3136                } catch (InterruptedException e) {
3137                }
3138                processStats.update();
3139
3140                // We'll take the stack crawls of just the top apps using CPU.
3141                final int N = processStats.countWorkingStats();
3142                int numProcs = 0;
3143                for (int i=0; i<N && numProcs<5; i++) {
3144                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3145                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3146                        numProcs++;
3147                        try {
3148                            synchronized (observer) {
3149                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3150                                observer.wait(200);  // Wait for write-close, give up after 200msec
3151                            }
3152                        } catch (InterruptedException e) {
3153                            Log.wtf(TAG, e);
3154                        }
3155
3156                    }
3157                }
3158            }
3159
3160        } finally {
3161            observer.stopWatching();
3162        }
3163
3164        if (nativeProcs != null) {
3165            int[] pids = Process.getPidsForCommands(nativeProcs);
3166            if (pids != null) {
3167                for (int pid : pids) {
3168                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3169                }
3170            }
3171        }
3172    }
3173
3174    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3175        if (true || IS_USER_BUILD) {
3176            return;
3177        }
3178        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3179        if (tracesPath == null || tracesPath.length() == 0) {
3180            return;
3181        }
3182
3183        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3184        StrictMode.allowThreadDiskWrites();
3185        try {
3186            final File tracesFile = new File(tracesPath);
3187            final File tracesDir = tracesFile.getParentFile();
3188            final File tracesTmp = new File(tracesDir, "__tmp__");
3189            try {
3190                if (!tracesDir.exists()) {
3191                    tracesFile.mkdirs();
3192                    if (!SELinux.restorecon(tracesDir.getPath())) {
3193                        return;
3194                    }
3195                }
3196                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3197
3198                if (tracesFile.exists()) {
3199                    tracesTmp.delete();
3200                    tracesFile.renameTo(tracesTmp);
3201                }
3202                StringBuilder sb = new StringBuilder();
3203                Time tobj = new Time();
3204                tobj.set(System.currentTimeMillis());
3205                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3206                sb.append(": ");
3207                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3208                sb.append(" since ");
3209                sb.append(msg);
3210                FileOutputStream fos = new FileOutputStream(tracesFile);
3211                fos.write(sb.toString().getBytes());
3212                if (app == null) {
3213                    fos.write("\n*** No application process!".getBytes());
3214                }
3215                fos.close();
3216                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3217            } catch (IOException e) {
3218                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3219                return;
3220            }
3221
3222            if (app != null) {
3223                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3224                firstPids.add(app.pid);
3225                dumpStackTraces(tracesPath, firstPids, null, null, null);
3226            }
3227
3228            File lastTracesFile = null;
3229            File curTracesFile = null;
3230            for (int i=9; i>=0; i--) {
3231                String name = String.format("slow%02d.txt", i);
3232                curTracesFile = new File(tracesDir, name);
3233                if (curTracesFile.exists()) {
3234                    if (lastTracesFile != null) {
3235                        curTracesFile.renameTo(lastTracesFile);
3236                    } else {
3237                        curTracesFile.delete();
3238                    }
3239                }
3240                lastTracesFile = curTracesFile;
3241            }
3242            tracesFile.renameTo(curTracesFile);
3243            if (tracesTmp.exists()) {
3244                tracesTmp.renameTo(tracesFile);
3245            }
3246        } finally {
3247            StrictMode.setThreadPolicy(oldPolicy);
3248        }
3249    }
3250
3251    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3252            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3253        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3254        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3255
3256        if (mController != null) {
3257            try {
3258                // 0 == continue, -1 = kill process immediately
3259                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3260                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3261            } catch (RemoteException e) {
3262                mController = null;
3263            }
3264        }
3265
3266        long anrTime = SystemClock.uptimeMillis();
3267        if (MONITOR_CPU_USAGE) {
3268            updateCpuStatsNow();
3269        }
3270
3271        synchronized (this) {
3272            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3273            if (mShuttingDown) {
3274                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3275                return;
3276            } else if (app.notResponding) {
3277                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3278                return;
3279            } else if (app.crashing) {
3280                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3281                return;
3282            }
3283
3284            // In case we come through here for the same app before completing
3285            // this one, mark as anring now so we will bail out.
3286            app.notResponding = true;
3287
3288            // Log the ANR to the event log.
3289            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3290                    app.processName, app.info.flags, annotation);
3291
3292            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3293            firstPids.add(app.pid);
3294
3295            int parentPid = app.pid;
3296            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3297            if (parentPid != app.pid) firstPids.add(parentPid);
3298
3299            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3300
3301            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3302                ProcessRecord r = mLruProcesses.get(i);
3303                if (r != null && r.thread != null) {
3304                    int pid = r.pid;
3305                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3306                        if (r.persistent) {
3307                            firstPids.add(pid);
3308                        } else {
3309                            lastPids.put(pid, Boolean.TRUE);
3310                        }
3311                    }
3312                }
3313            }
3314        }
3315
3316        // Log the ANR to the main log.
3317        StringBuilder info = new StringBuilder();
3318        info.setLength(0);
3319        info.append("ANR in ").append(app.processName);
3320        if (activity != null && activity.shortComponentName != null) {
3321            info.append(" (").append(activity.shortComponentName).append(")");
3322        }
3323        info.append("\n");
3324        if (annotation != null) {
3325            info.append("Reason: ").append(annotation).append("\n");
3326        }
3327        if (parent != null && parent != activity) {
3328            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3329        }
3330
3331        final ProcessStats processStats = new ProcessStats(true);
3332
3333        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3334
3335        String cpuInfo = null;
3336        if (MONITOR_CPU_USAGE) {
3337            updateCpuStatsNow();
3338            synchronized (mProcessStatsThread) {
3339                cpuInfo = mProcessStats.printCurrentState(anrTime);
3340            }
3341            info.append(processStats.printCurrentLoad());
3342            info.append(cpuInfo);
3343        }
3344
3345        info.append(processStats.printCurrentState(anrTime));
3346
3347        Slog.e(TAG, info.toString());
3348        if (tracesFile == null) {
3349            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3350            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3351        }
3352
3353        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3354                cpuInfo, tracesFile, null);
3355
3356        if (mController != null) {
3357            try {
3358                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3359                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3360                if (res != 0) {
3361                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3362                    return;
3363                }
3364            } catch (RemoteException e) {
3365                mController = null;
3366            }
3367        }
3368
3369        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3370        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3371                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3372
3373        synchronized (this) {
3374            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3375                Slog.w(TAG, "Killing " + app + ": background ANR");
3376                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3377                        app.processName, app.setAdj, "background ANR");
3378                Process.killProcessQuiet(app.pid);
3379                return;
3380            }
3381
3382            // Set the app's notResponding state, and look up the errorReportReceiver
3383            makeAppNotRespondingLocked(app,
3384                    activity != null ? activity.shortComponentName : null,
3385                    annotation != null ? "ANR " + annotation : "ANR",
3386                    info.toString());
3387
3388            // Bring up the infamous App Not Responding dialog
3389            Message msg = Message.obtain();
3390            HashMap map = new HashMap();
3391            msg.what = SHOW_NOT_RESPONDING_MSG;
3392            msg.obj = map;
3393            msg.arg1 = aboveSystem ? 1 : 0;
3394            map.put("app", app);
3395            if (activity != null) {
3396                map.put("activity", activity);
3397            }
3398
3399            mHandler.sendMessage(msg);
3400        }
3401    }
3402
3403    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3404        if (!mLaunchWarningShown) {
3405            mLaunchWarningShown = true;
3406            mHandler.post(new Runnable() {
3407                @Override
3408                public void run() {
3409                    synchronized (ActivityManagerService.this) {
3410                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3411                        d.show();
3412                        mHandler.postDelayed(new Runnable() {
3413                            @Override
3414                            public void run() {
3415                                synchronized (ActivityManagerService.this) {
3416                                    d.dismiss();
3417                                    mLaunchWarningShown = false;
3418                                }
3419                            }
3420                        }, 4000);
3421                    }
3422                }
3423            });
3424        }
3425    }
3426
3427    public boolean clearApplicationUserData(final String packageName,
3428            final IPackageDataObserver observer, int userId) {
3429        enforceNotIsolatedCaller("clearApplicationUserData");
3430        int uid = Binder.getCallingUid();
3431        int pid = Binder.getCallingPid();
3432        userId = handleIncomingUser(pid, uid,
3433                userId, false, true, "clearApplicationUserData", null);
3434        long callingId = Binder.clearCallingIdentity();
3435        try {
3436            IPackageManager pm = AppGlobals.getPackageManager();
3437            int pkgUid = -1;
3438            synchronized(this) {
3439                try {
3440                    pkgUid = pm.getPackageUid(packageName, userId);
3441                } catch (RemoteException e) {
3442                }
3443                if (pkgUid == -1) {
3444                    Slog.w(TAG, "Invalid packageName:" + packageName);
3445                    return false;
3446                }
3447                if (uid == pkgUid || checkComponentPermission(
3448                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3449                        pid, uid, -1, true)
3450                        == PackageManager.PERMISSION_GRANTED) {
3451                    forceStopPackageLocked(packageName, pkgUid);
3452                } else {
3453                    throw new SecurityException(pid+" does not have permission:"+
3454                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3455                                    "for process:"+packageName);
3456                }
3457            }
3458
3459            try {
3460                //clear application user data
3461                pm.clearApplicationUserData(packageName, observer, userId);
3462                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3463                        Uri.fromParts("package", packageName, null));
3464                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3465                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3466                        null, null, 0, null, null, null, false, false, userId);
3467            } catch (RemoteException e) {
3468            }
3469        } finally {
3470            Binder.restoreCallingIdentity(callingId);
3471        }
3472        return true;
3473    }
3474
3475    public void killBackgroundProcesses(final String packageName, int userId) {
3476        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3477                != PackageManager.PERMISSION_GRANTED &&
3478                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3479                        != PackageManager.PERMISSION_GRANTED) {
3480            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3481                    + Binder.getCallingPid()
3482                    + ", uid=" + Binder.getCallingUid()
3483                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3484            Slog.w(TAG, msg);
3485            throw new SecurityException(msg);
3486        }
3487
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3489                userId, true, true, "killBackgroundProcesses", null);
3490        long callingId = Binder.clearCallingIdentity();
3491        try {
3492            IPackageManager pm = AppGlobals.getPackageManager();
3493            synchronized(this) {
3494                int appId = -1;
3495                try {
3496                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3497                } catch (RemoteException e) {
3498                }
3499                if (appId == -1) {
3500                    Slog.w(TAG, "Invalid packageName: " + packageName);
3501                    return;
3502                }
3503                killPackageProcessesLocked(packageName, appId, userId,
3504                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3505            }
3506        } finally {
3507            Binder.restoreCallingIdentity(callingId);
3508        }
3509    }
3510
3511    public void killAllBackgroundProcesses() {
3512        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521
3522        long callingId = Binder.clearCallingIdentity();
3523        try {
3524            synchronized(this) {
3525                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3526                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3527                    final int NA = apps.size();
3528                    for (int ia=0; ia<NA; ia++) {
3529                        ProcessRecord app = apps.valueAt(ia);
3530                        if (app.persistent) {
3531                            // we don't kill persistent processes
3532                            continue;
3533                        }
3534                        if (app.removed) {
3535                            procs.add(app);
3536                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3537                            app.removed = true;
3538                            procs.add(app);
3539                        }
3540                    }
3541                }
3542
3543                int N = procs.size();
3544                for (int i=0; i<N; i++) {
3545                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3546                }
3547            }
3548        } finally {
3549            Binder.restoreCallingIdentity(callingId);
3550        }
3551    }
3552
3553    public void forceStopPackage(final String packageName, int userId) {
3554        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3555                != PackageManager.PERMISSION_GRANTED) {
3556            String msg = "Permission Denial: forceStopPackage() from pid="
3557                    + Binder.getCallingPid()
3558                    + ", uid=" + Binder.getCallingUid()
3559                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3560            Slog.w(TAG, msg);
3561            throw new SecurityException(msg);
3562        }
3563        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3564                userId, true, true, "forceStopPackage", null);
3565        long callingId = Binder.clearCallingIdentity();
3566        try {
3567            IPackageManager pm = AppGlobals.getPackageManager();
3568            synchronized(this) {
3569                int[] users = userId == UserHandle.USER_ALL
3570                        ? getUsersLocked() : new int[] { userId };
3571                for (int user : users) {
3572                    int pkgUid = -1;
3573                    try {
3574                        pkgUid = pm.getPackageUid(packageName, user);
3575                    } catch (RemoteException e) {
3576                    }
3577                    if (pkgUid == -1) {
3578                        Slog.w(TAG, "Invalid packageName: " + packageName);
3579                        continue;
3580                    }
3581                    try {
3582                        pm.setPackageStoppedState(packageName, true, user);
3583                    } catch (RemoteException e) {
3584                    } catch (IllegalArgumentException e) {
3585                        Slog.w(TAG, "Failed trying to unstop package "
3586                                + packageName + ": " + e);
3587                    }
3588                    if (isUserRunningLocked(user, false)) {
3589                        forceStopPackageLocked(packageName, pkgUid);
3590                    }
3591                }
3592            }
3593        } finally {
3594            Binder.restoreCallingIdentity(callingId);
3595        }
3596    }
3597
3598    /*
3599     * The pkg name and app id have to be specified.
3600     */
3601    public void killApplicationWithAppId(String pkg, int appid) {
3602        if (pkg == null) {
3603            return;
3604        }
3605        // Make sure the uid is valid.
3606        if (appid < 0) {
3607            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3608            return;
3609        }
3610        int callerUid = Binder.getCallingUid();
3611        // Only the system server can kill an application
3612        if (callerUid == Process.SYSTEM_UID) {
3613            // Post an aysnc message to kill the application
3614            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3615            msg.arg1 = appid;
3616            msg.arg2 = 0;
3617            msg.obj = pkg;
3618            mHandler.sendMessage(msg);
3619        } else {
3620            throw new SecurityException(callerUid + " cannot kill pkg: " +
3621                    pkg);
3622        }
3623    }
3624
3625    public void closeSystemDialogs(String reason) {
3626        enforceNotIsolatedCaller("closeSystemDialogs");
3627
3628        final int pid = Binder.getCallingPid();
3629        final int uid = Binder.getCallingUid();
3630        final long origId = Binder.clearCallingIdentity();
3631        try {
3632            synchronized (this) {
3633                // Only allow this from foreground processes, so that background
3634                // applications can't abuse it to prevent system UI from being shown.
3635                if (uid >= Process.FIRST_APPLICATION_UID) {
3636                    ProcessRecord proc;
3637                    synchronized (mPidsSelfLocked) {
3638                        proc = mPidsSelfLocked.get(pid);
3639                    }
3640                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3641                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3642                                + " from background process " + proc);
3643                        return;
3644                    }
3645                }
3646                closeSystemDialogsLocked(reason);
3647            }
3648        } finally {
3649            Binder.restoreCallingIdentity(origId);
3650        }
3651    }
3652
3653    void closeSystemDialogsLocked(String reason) {
3654        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3655        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3656                | Intent.FLAG_RECEIVER_FOREGROUND);
3657        if (reason != null) {
3658            intent.putExtra("reason", reason);
3659        }
3660        mWindowManager.closeSystemDialogs(reason);
3661
3662        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3663            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3664            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3665                r.stack.finishActivityLocked(r, i,
3666                        Activity.RESULT_CANCELED, null, "close-sys", true);
3667            }
3668        }
3669
3670        broadcastIntentLocked(null, null, intent, null,
3671                null, 0, null, null, null, false, false, -1,
3672                Process.SYSTEM_UID, UserHandle.USER_ALL);
3673    }
3674
3675    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3676            throws RemoteException {
3677        enforceNotIsolatedCaller("getProcessMemoryInfo");
3678        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3679        for (int i=pids.length-1; i>=0; i--) {
3680            infos[i] = new Debug.MemoryInfo();
3681            Debug.getMemoryInfo(pids[i], infos[i]);
3682        }
3683        return infos;
3684    }
3685
3686    public long[] getProcessPss(int[] pids) throws RemoteException {
3687        enforceNotIsolatedCaller("getProcessPss");
3688        long[] pss = new long[pids.length];
3689        for (int i=pids.length-1; i>=0; i--) {
3690            pss[i] = Debug.getPss(pids[i]);
3691        }
3692        return pss;
3693    }
3694
3695    public void killApplicationProcess(String processName, int uid) {
3696        if (processName == null) {
3697            return;
3698        }
3699
3700        int callerUid = Binder.getCallingUid();
3701        // Only the system server can kill an application
3702        if (callerUid == Process.SYSTEM_UID) {
3703            synchronized (this) {
3704                ProcessRecord app = getProcessRecordLocked(processName, uid);
3705                if (app != null && app.thread != null) {
3706                    try {
3707                        app.thread.scheduleSuicide();
3708                    } catch (RemoteException e) {
3709                        // If the other end already died, then our work here is done.
3710                    }
3711                } else {
3712                    Slog.w(TAG, "Process/uid not found attempting kill of "
3713                            + processName + " / " + uid);
3714                }
3715            }
3716        } else {
3717            throw new SecurityException(callerUid + " cannot kill app process: " +
3718                    processName);
3719        }
3720    }
3721
3722    private void forceStopPackageLocked(final String packageName, int uid) {
3723        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3724                false, true, false, UserHandle.getUserId(uid));
3725        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3726                Uri.fromParts("package", packageName, null));
3727        if (!mProcessesReady) {
3728            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3729                    | Intent.FLAG_RECEIVER_FOREGROUND);
3730        }
3731        intent.putExtra(Intent.EXTRA_UID, uid);
3732        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3733        broadcastIntentLocked(null, null, intent,
3734                null, null, 0, null, null, null,
3735                false, false,
3736                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3737    }
3738
3739    private void forceStopUserLocked(int userId) {
3740        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3741        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3743                | Intent.FLAG_RECEIVER_FOREGROUND);
3744        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3745        broadcastIntentLocked(null, null, intent,
3746                null, null, 0, null, null, null,
3747                false, false,
3748                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3749    }
3750
3751    private final boolean killPackageProcessesLocked(String packageName, int appId,
3752            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3753            boolean doit, boolean evenPersistent, String reason) {
3754        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3755
3756        // Remove all processes this package may have touched: all with the
3757        // same UID (except for the system or root user), and all whose name
3758        // matches the package name.
3759        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3760        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3761            final int NA = apps.size();
3762            for (int ia=0; ia<NA; ia++) {
3763                ProcessRecord app = apps.valueAt(ia);
3764                if (app.persistent && !evenPersistent) {
3765                    // we don't kill persistent processes
3766                    continue;
3767                }
3768                if (app.removed) {
3769                    if (doit) {
3770                        procs.add(app);
3771                    }
3772                    continue;
3773                }
3774
3775                // Skip process if it doesn't meet our oom adj requirement.
3776                if (app.setAdj < minOomAdj) {
3777                    continue;
3778                }
3779
3780                // If no package is specified, we call all processes under the
3781                // give user id.
3782                if (packageName == null) {
3783                    if (app.userId != userId) {
3784                        continue;
3785                    }
3786                // Package has been specified, we want to hit all processes
3787                // that match it.  We need to qualify this by the processes
3788                // that are running under the specified app and user ID.
3789                } else {
3790                    if (UserHandle.getAppId(app.uid) != appId) {
3791                        continue;
3792                    }
3793                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3794                        continue;
3795                    }
3796                    if (!app.pkgList.contains(packageName)) {
3797                        continue;
3798                    }
3799                }
3800
3801                // Process has passed all conditions, kill it!
3802                if (!doit) {
3803                    return true;
3804                }
3805                app.removed = true;
3806                procs.add(app);
3807            }
3808        }
3809
3810        int N = procs.size();
3811        for (int i=0; i<N; i++) {
3812            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3813        }
3814        return N > 0;
3815    }
3816
3817    private final boolean forceStopPackageLocked(String name, int appId,
3818            boolean callerWillRestart, boolean purgeCache, boolean doit,
3819            boolean evenPersistent, int userId) {
3820        int i;
3821        int N;
3822
3823        if (userId == UserHandle.USER_ALL && name == null) {
3824            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3825        }
3826
3827        if (appId < 0 && name != null) {
3828            try {
3829                appId = UserHandle.getAppId(
3830                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3831            } catch (RemoteException e) {
3832            }
3833        }
3834
3835        if (doit) {
3836            if (name != null) {
3837                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3838                        + " user=" + userId);
3839            } else {
3840                Slog.i(TAG, "Force stopping user " + userId);
3841            }
3842
3843            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3844            while (badApps.hasNext()) {
3845                SparseArray<Long> ba = badApps.next();
3846                for (i=ba.size()-1; i>=0; i--) {
3847                    boolean remove = false;
3848                    final int entUid = ba.keyAt(i);
3849                    if (name != null) {
3850                        if (userId == UserHandle.USER_ALL) {
3851                            if (UserHandle.getAppId(entUid) == appId) {
3852                                remove = true;
3853                            }
3854                        } else {
3855                            if (entUid == UserHandle.getUid(userId, appId)) {
3856                                remove = true;
3857                            }
3858                        }
3859                    } else if (UserHandle.getUserId(entUid) == userId) {
3860                        remove = true;
3861                    }
3862                    if (remove) {
3863                        ba.removeAt(i);
3864                    }
3865                }
3866                if (ba.size() == 0) {
3867                    badApps.remove();
3868                }
3869            }
3870        }
3871
3872        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3873                -100, callerWillRestart, false, doit, evenPersistent,
3874                name == null ? ("force stop user " + userId) : ("force stop " + name));
3875
3876        TaskRecord lastTask = null;
3877        for (i=0; i<mMainStack.mHistory.size(); i++) {
3878            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3879            final boolean samePackage = r.packageName.equals(name)
3880                    || (name == null && r.userId == userId);
3881            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3882                    && (samePackage || r.task == lastTask)
3883                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3884                if (!doit) {
3885                    if (r.finishing) {
3886                        // If this activity is just finishing, then it is not
3887                        // interesting as far as something to stop.
3888                        continue;
3889                    }
3890                    return true;
3891                }
3892                didSomething = true;
3893                Slog.i(TAG, "  Force finishing activity " + r);
3894                if (samePackage) {
3895                    if (r.app != null) {
3896                        r.app.removed = true;
3897                    }
3898                    r.app = null;
3899                }
3900                lastTask = r.task;
3901                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3902                        null, "force-stop", true)) {
3903                    i--;
3904                }
3905            }
3906        }
3907
3908        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3909            if (!doit) {
3910                return true;
3911            }
3912            didSomething = true;
3913        }
3914
3915        if (name == null) {
3916            // Remove all sticky broadcasts from this user.
3917            mStickyBroadcasts.remove(userId);
3918        }
3919
3920        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3921        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3922                userId, providers)) {
3923            if (!doit) {
3924                return true;
3925            }
3926            didSomething = true;
3927        }
3928        N = providers.size();
3929        for (i=0; i<N; i++) {
3930            removeDyingProviderLocked(null, providers.get(i), true);
3931        }
3932
3933        if (mIntentSenderRecords.size() > 0) {
3934            Iterator<WeakReference<PendingIntentRecord>> it
3935                    = mIntentSenderRecords.values().iterator();
3936            while (it.hasNext()) {
3937                WeakReference<PendingIntentRecord> wpir = it.next();
3938                if (wpir == null) {
3939                    it.remove();
3940                    continue;
3941                }
3942                PendingIntentRecord pir = wpir.get();
3943                if (pir == null) {
3944                    it.remove();
3945                    continue;
3946                }
3947                if (name == null) {
3948                    // Stopping user, remove all objects for the user.
3949                    if (pir.key.userId != userId) {
3950                        // Not the same user, skip it.
3951                        continue;
3952                    }
3953                } else {
3954                    if (UserHandle.getAppId(pir.uid) != appId) {
3955                        // Different app id, skip it.
3956                        continue;
3957                    }
3958                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3959                        // Different user, skip it.
3960                        continue;
3961                    }
3962                    if (!pir.key.packageName.equals(name)) {
3963                        // Different package, skip it.
3964                        continue;
3965                    }
3966                }
3967                if (!doit) {
3968                    return true;
3969                }
3970                didSomething = true;
3971                it.remove();
3972                pir.canceled = true;
3973                if (pir.key.activity != null) {
3974                    pir.key.activity.pendingResults.remove(pir.ref);
3975                }
3976            }
3977        }
3978
3979        if (doit) {
3980            if (purgeCache && name != null) {
3981                AttributeCache ac = AttributeCache.instance();
3982                if (ac != null) {
3983                    ac.removePackage(name);
3984                }
3985            }
3986            if (mBooted) {
3987                mMainStack.resumeTopActivityLocked(null);
3988                mMainStack.scheduleIdleLocked();
3989            }
3990        }
3991
3992        return didSomething;
3993    }
3994
3995    private final boolean removeProcessLocked(ProcessRecord app,
3996            boolean callerWillRestart, boolean allowRestart, String reason) {
3997        final String name = app.processName;
3998        final int uid = app.uid;
3999        if (DEBUG_PROCESSES) Slog.d(
4000            TAG, "Force removing proc " + app.toShortString() + " (" + name
4001            + "/" + uid + ")");
4002
4003        mProcessNames.remove(name, uid);
4004        mIsolatedProcesses.remove(app.uid);
4005        if (mHeavyWeightProcess == app) {
4006            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4007                    mHeavyWeightProcess.userId, 0));
4008            mHeavyWeightProcess = null;
4009        }
4010        boolean needRestart = false;
4011        if (app.pid > 0 && app.pid != MY_PID) {
4012            int pid = app.pid;
4013            synchronized (mPidsSelfLocked) {
4014                mPidsSelfLocked.remove(pid);
4015                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4016            }
4017            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4018            handleAppDiedLocked(app, true, allowRestart);
4019            mLruProcesses.remove(app);
4020            Process.killProcessQuiet(pid);
4021
4022            if (app.persistent && !app.isolated) {
4023                if (!callerWillRestart) {
4024                    addAppLocked(app.info, false);
4025                } else {
4026                    needRestart = true;
4027                }
4028            }
4029        } else {
4030            mRemovedProcesses.add(app);
4031        }
4032
4033        return needRestart;
4034    }
4035
4036    private final void processStartTimedOutLocked(ProcessRecord app) {
4037        final int pid = app.pid;
4038        boolean gone = false;
4039        synchronized (mPidsSelfLocked) {
4040            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4041            if (knownApp != null && knownApp.thread == null) {
4042                mPidsSelfLocked.remove(pid);
4043                gone = true;
4044            }
4045        }
4046
4047        if (gone) {
4048            Slog.w(TAG, "Process " + app + " failed to attach");
4049            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4050                    pid, app.uid, app.processName);
4051            mProcessNames.remove(app.processName, app.uid);
4052            mIsolatedProcesses.remove(app.uid);
4053            if (mHeavyWeightProcess == app) {
4054                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4055                        mHeavyWeightProcess.userId, 0));
4056                mHeavyWeightProcess = null;
4057            }
4058            // Take care of any launching providers waiting for this process.
4059            checkAppInLaunchingProvidersLocked(app, true);
4060            // Take care of any services that are waiting for the process.
4061            mServices.processStartTimedOutLocked(app);
4062            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4063                    app.processName, app.setAdj, "start timeout");
4064            Process.killProcessQuiet(pid);
4065            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4066                Slog.w(TAG, "Unattached app died before backup, skipping");
4067                try {
4068                    IBackupManager bm = IBackupManager.Stub.asInterface(
4069                            ServiceManager.getService(Context.BACKUP_SERVICE));
4070                    bm.agentDisconnected(app.info.packageName);
4071                } catch (RemoteException e) {
4072                    // Can't happen; the backup manager is local
4073                }
4074            }
4075            if (isPendingBroadcastProcessLocked(pid)) {
4076                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4077                skipPendingBroadcastLocked(pid);
4078            }
4079        } else {
4080            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4081        }
4082    }
4083
4084    private final boolean attachApplicationLocked(IApplicationThread thread,
4085            int pid) {
4086
4087        // Find the application record that is being attached...  either via
4088        // the pid if we are running in multiple processes, or just pull the
4089        // next app record if we are emulating process with anonymous threads.
4090        ProcessRecord app;
4091        if (pid != MY_PID && pid >= 0) {
4092            synchronized (mPidsSelfLocked) {
4093                app = mPidsSelfLocked.get(pid);
4094            }
4095        } else {
4096            app = null;
4097        }
4098
4099        if (app == null) {
4100            Slog.w(TAG, "No pending application record for pid " + pid
4101                    + " (IApplicationThread " + thread + "); dropping process");
4102            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4103            if (pid > 0 && pid != MY_PID) {
4104                Process.killProcessQuiet(pid);
4105            } else {
4106                try {
4107                    thread.scheduleExit();
4108                } catch (Exception e) {
4109                    // Ignore exceptions.
4110                }
4111            }
4112            return false;
4113        }
4114
4115        // If this application record is still attached to a previous
4116        // process, clean it up now.
4117        if (app.thread != null) {
4118            handleAppDiedLocked(app, true, true);
4119        }
4120
4121        // Tell the process all about itself.
4122
4123        if (localLOGV) Slog.v(
4124                TAG, "Binding process pid " + pid + " to record " + app);
4125
4126        String processName = app.processName;
4127        try {
4128            AppDeathRecipient adr = new AppDeathRecipient(
4129                    app, pid, thread);
4130            thread.asBinder().linkToDeath(adr, 0);
4131            app.deathRecipient = adr;
4132        } catch (RemoteException e) {
4133            app.resetPackageList();
4134            startProcessLocked(app, "link fail", processName);
4135            return false;
4136        }
4137
4138        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4139
4140        app.thread = thread;
4141        app.curAdj = app.setAdj = -100;
4142        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4143        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4144        app.forcingToForeground = null;
4145        app.foregroundServices = false;
4146        app.hasShownUi = false;
4147        app.debugging = false;
4148
4149        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4150
4151        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4152        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4153
4154        if (!normalMode) {
4155            Slog.i(TAG, "Launching preboot mode app: " + app);
4156        }
4157
4158        if (localLOGV) Slog.v(
4159            TAG, "New app record " + app
4160            + " thread=" + thread.asBinder() + " pid=" + pid);
4161        try {
4162            int testMode = IApplicationThread.DEBUG_OFF;
4163            if (mDebugApp != null && mDebugApp.equals(processName)) {
4164                testMode = mWaitForDebugger
4165                    ? IApplicationThread.DEBUG_WAIT
4166                    : IApplicationThread.DEBUG_ON;
4167                app.debugging = true;
4168                if (mDebugTransient) {
4169                    mDebugApp = mOrigDebugApp;
4170                    mWaitForDebugger = mOrigWaitForDebugger;
4171                }
4172            }
4173            String profileFile = app.instrumentationProfileFile;
4174            ParcelFileDescriptor profileFd = null;
4175            boolean profileAutoStop = false;
4176            if (mProfileApp != null && mProfileApp.equals(processName)) {
4177                mProfileProc = app;
4178                profileFile = mProfileFile;
4179                profileFd = mProfileFd;
4180                profileAutoStop = mAutoStopProfiler;
4181            }
4182            boolean enableOpenGlTrace = false;
4183            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4184                enableOpenGlTrace = true;
4185                mOpenGlTraceApp = null;
4186            }
4187
4188            // If the app is being launched for restore or full backup, set it up specially
4189            boolean isRestrictedBackupMode = false;
4190            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4191                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4192                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4193                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4194            }
4195
4196            ensurePackageDexOpt(app.instrumentationInfo != null
4197                    ? app.instrumentationInfo.packageName
4198                    : app.info.packageName);
4199            if (app.instrumentationClass != null) {
4200                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4201            }
4202            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4203                    + processName + " with config " + mConfiguration);
4204            ApplicationInfo appInfo = app.instrumentationInfo != null
4205                    ? app.instrumentationInfo : app.info;
4206            app.compat = compatibilityInfoForPackageLocked(appInfo);
4207            if (profileFd != null) {
4208                profileFd = profileFd.dup();
4209            }
4210            thread.bindApplication(processName, appInfo, providers,
4211                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4212                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4213                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4214                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4215                    mCoreSettingsObserver.getCoreSettingsLocked());
4216            updateLruProcessLocked(app, false);
4217            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4218        } catch (Exception e) {
4219            // todo: Yikes!  What should we do?  For now we will try to
4220            // start another process, but that could easily get us in
4221            // an infinite loop of restarting processes...
4222            Slog.w(TAG, "Exception thrown during bind!", e);
4223
4224            app.resetPackageList();
4225            app.unlinkDeathRecipient();
4226            startProcessLocked(app, "bind fail", processName);
4227            return false;
4228        }
4229
4230        // Remove this record from the list of starting applications.
4231        mPersistentStartingProcesses.remove(app);
4232        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4233                "Attach application locked removing on hold: " + app);
4234        mProcessesOnHold.remove(app);
4235
4236        boolean badApp = false;
4237        boolean didSomething = false;
4238
4239        // See if the top visible activity is waiting to run in this process...
4240        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4241        if (hr != null && normalMode) {
4242            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4243                    && processName.equals(hr.processName)) {
4244                try {
4245                    if (mHeadless) {
4246                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4247                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4248                        didSomething = true;
4249                    }
4250                } catch (Exception e) {
4251                    Slog.w(TAG, "Exception in new application when starting activity "
4252                          + hr.intent.getComponent().flattenToShortString(), e);
4253                    badApp = true;
4254                }
4255            } else {
4256                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4257            }
4258        }
4259
4260        // Find any services that should be running in this process...
4261        if (!badApp) {
4262            try {
4263                didSomething |= mServices.attachApplicationLocked(app, processName);
4264            } catch (Exception e) {
4265                badApp = true;
4266            }
4267        }
4268
4269        // Check if a next-broadcast receiver is in this process...
4270        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4271            try {
4272                didSomething = sendPendingBroadcastsLocked(app);
4273            } catch (Exception e) {
4274                // If the app died trying to launch the receiver we declare it 'bad'
4275                badApp = true;
4276            }
4277        }
4278
4279        // Check whether the next backup agent is in this process...
4280        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4281            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4282            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4283            try {
4284                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4285                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4286                        mBackupTarget.backupMode);
4287            } catch (Exception e) {
4288                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4289                e.printStackTrace();
4290            }
4291        }
4292
4293        if (badApp) {
4294            // todo: Also need to kill application to deal with all
4295            // kinds of exceptions.
4296            handleAppDiedLocked(app, false, true);
4297            return false;
4298        }
4299
4300        if (!didSomething) {
4301            updateOomAdjLocked();
4302        }
4303
4304        return true;
4305    }
4306
4307    public final void attachApplication(IApplicationThread thread) {
4308        synchronized (this) {
4309            int callingPid = Binder.getCallingPid();
4310            final long origId = Binder.clearCallingIdentity();
4311            attachApplicationLocked(thread, callingPid);
4312            Binder.restoreCallingIdentity(origId);
4313        }
4314    }
4315
4316    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4317        final long origId = Binder.clearCallingIdentity();
4318        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4319        if (stopProfiling) {
4320            synchronized (this) {
4321                if (mProfileProc == r.app) {
4322                    if (mProfileFd != null) {
4323                        try {
4324                            mProfileFd.close();
4325                        } catch (IOException e) {
4326                        }
4327                        clearProfilerLocked();
4328                    }
4329                }
4330            }
4331        }
4332        Binder.restoreCallingIdentity(origId);
4333    }
4334
4335    void enableScreenAfterBoot() {
4336        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4337                SystemClock.uptimeMillis());
4338        mWindowManager.enableScreenAfterBoot();
4339
4340        synchronized (this) {
4341            updateEventDispatchingLocked();
4342        }
4343    }
4344
4345    public void showBootMessage(final CharSequence msg, final boolean always) {
4346        enforceNotIsolatedCaller("showBootMessage");
4347        mWindowManager.showBootMessage(msg, always);
4348    }
4349
4350    public void dismissKeyguardOnNextActivity() {
4351        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4352        final long token = Binder.clearCallingIdentity();
4353        try {
4354            synchronized (this) {
4355                if (mLockScreenShown) {
4356                    mLockScreenShown = false;
4357                    comeOutOfSleepIfNeededLocked();
4358                }
4359                mMainStack.dismissKeyguardOnNextActivityLocked();
4360            }
4361        } finally {
4362            Binder.restoreCallingIdentity(token);
4363        }
4364    }
4365
4366    final void finishBooting() {
4367        IntentFilter pkgFilter = new IntentFilter();
4368        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4369        pkgFilter.addDataScheme("package");
4370        mContext.registerReceiver(new BroadcastReceiver() {
4371            @Override
4372            public void onReceive(Context context, Intent intent) {
4373                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4374                if (pkgs != null) {
4375                    for (String pkg : pkgs) {
4376                        synchronized (ActivityManagerService.this) {
4377                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4378                                setResultCode(Activity.RESULT_OK);
4379                                return;
4380                            }
4381                        }
4382                    }
4383                }
4384            }
4385        }, pkgFilter);
4386
4387        synchronized (this) {
4388            // Ensure that any processes we had put on hold are now started
4389            // up.
4390            final int NP = mProcessesOnHold.size();
4391            if (NP > 0) {
4392                ArrayList<ProcessRecord> procs =
4393                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4394                for (int ip=0; ip<NP; ip++) {
4395                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4396                            + procs.get(ip));
4397                    startProcessLocked(procs.get(ip), "on-hold", null);
4398                }
4399            }
4400
4401            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4402                // Start looking for apps that are abusing wake locks.
4403                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4404                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4405                // Tell anyone interested that we are done booting!
4406                SystemProperties.set("sys.boot_completed", "1");
4407                SystemProperties.set("dev.bootcomplete", "1");
4408                for (int i=0; i<mStartedUsers.size(); i++) {
4409                    UserStartedState uss = mStartedUsers.valueAt(i);
4410                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4411                        uss.mState = UserStartedState.STATE_RUNNING;
4412                        final int userId = mStartedUsers.keyAt(i);
4413                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4414                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4415                        broadcastIntentLocked(null, null, intent,
4416                                null, null, 0, null, null,
4417                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4418                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4419                    }
4420                }
4421            }
4422        }
4423    }
4424
4425    final void ensureBootCompleted() {
4426        boolean booting;
4427        boolean enableScreen;
4428        synchronized (this) {
4429            booting = mBooting;
4430            mBooting = false;
4431            enableScreen = !mBooted;
4432            mBooted = true;
4433        }
4434
4435        if (booting) {
4436            finishBooting();
4437        }
4438
4439        if (enableScreen) {
4440            enableScreenAfterBoot();
4441        }
4442    }
4443
4444    public final void activityResumed(IBinder token) {
4445        final long origId = Binder.clearCallingIdentity();
4446        mMainStack.activityResumed(token);
4447        Binder.restoreCallingIdentity(origId);
4448    }
4449
4450    public final void activityPaused(IBinder token) {
4451        final long origId = Binder.clearCallingIdentity();
4452        mMainStack.activityPaused(token, false);
4453        Binder.restoreCallingIdentity(origId);
4454    }
4455
4456    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4457            CharSequence description) {
4458        if (localLOGV) Slog.v(
4459            TAG, "Activity stopped: token=" + token);
4460
4461        // Refuse possible leaked file descriptors
4462        if (icicle != null && icicle.hasFileDescriptors()) {
4463            throw new IllegalArgumentException("File descriptors passed in Bundle");
4464        }
4465
4466        ActivityRecord r = null;
4467
4468        final long origId = Binder.clearCallingIdentity();
4469
4470        synchronized (this) {
4471            r = mMainStack.isInStackLocked(token);
4472            if (r != null) {
4473                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4474            }
4475        }
4476
4477        if (r != null) {
4478            sendPendingThumbnail(r, null, null, null, false);
4479        }
4480
4481        trimApplications();
4482
4483        Binder.restoreCallingIdentity(origId);
4484    }
4485
4486    public final void activityDestroyed(IBinder token) {
4487        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4488        mMainStack.activityDestroyed(token);
4489    }
4490
4491    public String getCallingPackage(IBinder token) {
4492        synchronized (this) {
4493            ActivityRecord r = getCallingRecordLocked(token);
4494            return r != null && r.app != null ? r.info.packageName : null;
4495        }
4496    }
4497
4498    public ComponentName getCallingActivity(IBinder token) {
4499        synchronized (this) {
4500            ActivityRecord r = getCallingRecordLocked(token);
4501            return r != null ? r.intent.getComponent() : null;
4502        }
4503    }
4504
4505    private ActivityRecord getCallingRecordLocked(IBinder token) {
4506        ActivityRecord r = mMainStack.isInStackLocked(token);
4507        if (r == null) {
4508            return null;
4509        }
4510        return r.resultTo;
4511    }
4512
4513    public ComponentName getActivityClassForToken(IBinder token) {
4514        synchronized(this) {
4515            ActivityRecord r = mMainStack.isInStackLocked(token);
4516            if (r == null) {
4517                return null;
4518            }
4519            return r.intent.getComponent();
4520        }
4521    }
4522
4523    public String getPackageForToken(IBinder token) {
4524        synchronized(this) {
4525            ActivityRecord r = mMainStack.isInStackLocked(token);
4526            if (r == null) {
4527                return null;
4528            }
4529            return r.packageName;
4530        }
4531    }
4532
4533    public IIntentSender getIntentSender(int type,
4534            String packageName, IBinder token, String resultWho,
4535            int requestCode, Intent[] intents, String[] resolvedTypes,
4536            int flags, Bundle options, int userId) {
4537        enforceNotIsolatedCaller("getIntentSender");
4538        // Refuse possible leaked file descriptors
4539        if (intents != null) {
4540            if (intents.length < 1) {
4541                throw new IllegalArgumentException("Intents array length must be >= 1");
4542            }
4543            for (int i=0; i<intents.length; i++) {
4544                Intent intent = intents[i];
4545                if (intent != null) {
4546                    if (intent.hasFileDescriptors()) {
4547                        throw new IllegalArgumentException("File descriptors passed in Intent");
4548                    }
4549                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4550                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4551                        throw new IllegalArgumentException(
4552                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4553                    }
4554                    intents[i] = new Intent(intent);
4555                }
4556            }
4557            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4558                throw new IllegalArgumentException(
4559                        "Intent array length does not match resolvedTypes length");
4560            }
4561        }
4562        if (options != null) {
4563            if (options.hasFileDescriptors()) {
4564                throw new IllegalArgumentException("File descriptors passed in options");
4565            }
4566        }
4567
4568        synchronized(this) {
4569            int callingUid = Binder.getCallingUid();
4570            int origUserId = userId;
4571            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4572                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4573                    "getIntentSender", null);
4574            if (origUserId == UserHandle.USER_CURRENT) {
4575                // We don't want to evaluate this until the pending intent is
4576                // actually executed.  However, we do want to always do the
4577                // security checking for it above.
4578                userId = UserHandle.USER_CURRENT;
4579            }
4580            try {
4581                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4582                    int uid = AppGlobals.getPackageManager()
4583                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4584                    if (!UserHandle.isSameApp(callingUid, uid)) {
4585                        String msg = "Permission Denial: getIntentSender() from pid="
4586                            + Binder.getCallingPid()
4587                            + ", uid=" + Binder.getCallingUid()
4588                            + ", (need uid=" + uid + ")"
4589                            + " is not allowed to send as package " + packageName;
4590                        Slog.w(TAG, msg);
4591                        throw new SecurityException(msg);
4592                    }
4593                }
4594
4595                return getIntentSenderLocked(type, packageName, callingUid, userId,
4596                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4597
4598            } catch (RemoteException e) {
4599                throw new SecurityException(e);
4600            }
4601        }
4602    }
4603
4604    IIntentSender getIntentSenderLocked(int type, String packageName,
4605            int callingUid, int userId, IBinder token, String resultWho,
4606            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4607            Bundle options) {
4608        if (DEBUG_MU)
4609            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4610        ActivityRecord activity = null;
4611        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4612            activity = mMainStack.isInStackLocked(token);
4613            if (activity == null) {
4614                return null;
4615            }
4616            if (activity.finishing) {
4617                return null;
4618            }
4619        }
4620
4621        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4622        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4623        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4624        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4625                |PendingIntent.FLAG_UPDATE_CURRENT);
4626
4627        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4628                type, packageName, activity, resultWho,
4629                requestCode, intents, resolvedTypes, flags, options, userId);
4630        WeakReference<PendingIntentRecord> ref;
4631        ref = mIntentSenderRecords.get(key);
4632        PendingIntentRecord rec = ref != null ? ref.get() : null;
4633        if (rec != null) {
4634            if (!cancelCurrent) {
4635                if (updateCurrent) {
4636                    if (rec.key.requestIntent != null) {
4637                        rec.key.requestIntent.replaceExtras(intents != null ?
4638                                intents[intents.length - 1] : null);
4639                    }
4640                    if (intents != null) {
4641                        intents[intents.length-1] = rec.key.requestIntent;
4642                        rec.key.allIntents = intents;
4643                        rec.key.allResolvedTypes = resolvedTypes;
4644                    } else {
4645                        rec.key.allIntents = null;
4646                        rec.key.allResolvedTypes = null;
4647                    }
4648                }
4649                return rec;
4650            }
4651            rec.canceled = true;
4652            mIntentSenderRecords.remove(key);
4653        }
4654        if (noCreate) {
4655            return rec;
4656        }
4657        rec = new PendingIntentRecord(this, key, callingUid);
4658        mIntentSenderRecords.put(key, rec.ref);
4659        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4660            if (activity.pendingResults == null) {
4661                activity.pendingResults
4662                        = new HashSet<WeakReference<PendingIntentRecord>>();
4663            }
4664            activity.pendingResults.add(rec.ref);
4665        }
4666        return rec;
4667    }
4668
4669    public void cancelIntentSender(IIntentSender sender) {
4670        if (!(sender instanceof PendingIntentRecord)) {
4671            return;
4672        }
4673        synchronized(this) {
4674            PendingIntentRecord rec = (PendingIntentRecord)sender;
4675            try {
4676                int uid = AppGlobals.getPackageManager()
4677                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4678                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4679                    String msg = "Permission Denial: cancelIntentSender() from pid="
4680                        + Binder.getCallingPid()
4681                        + ", uid=" + Binder.getCallingUid()
4682                        + " is not allowed to cancel packges "
4683                        + rec.key.packageName;
4684                    Slog.w(TAG, msg);
4685                    throw new SecurityException(msg);
4686                }
4687            } catch (RemoteException e) {
4688                throw new SecurityException(e);
4689            }
4690            cancelIntentSenderLocked(rec, true);
4691        }
4692    }
4693
4694    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4695        rec.canceled = true;
4696        mIntentSenderRecords.remove(rec.key);
4697        if (cleanActivity && rec.key.activity != null) {
4698            rec.key.activity.pendingResults.remove(rec.ref);
4699        }
4700    }
4701
4702    public String getPackageForIntentSender(IIntentSender pendingResult) {
4703        if (!(pendingResult instanceof PendingIntentRecord)) {
4704            return null;
4705        }
4706        try {
4707            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4708            return res.key.packageName;
4709        } catch (ClassCastException e) {
4710        }
4711        return null;
4712    }
4713
4714    public int getUidForIntentSender(IIntentSender sender) {
4715        if (sender instanceof PendingIntentRecord) {
4716            try {
4717                PendingIntentRecord res = (PendingIntentRecord)sender;
4718                return res.uid;
4719            } catch (ClassCastException e) {
4720            }
4721        }
4722        return -1;
4723    }
4724
4725    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4726        if (!(pendingResult instanceof PendingIntentRecord)) {
4727            return false;
4728        }
4729        try {
4730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4731            if (res.key.allIntents == null) {
4732                return false;
4733            }
4734            for (int i=0; i<res.key.allIntents.length; i++) {
4735                Intent intent = res.key.allIntents[i];
4736                if (intent.getPackage() != null && intent.getComponent() != null) {
4737                    return false;
4738                }
4739            }
4740            return true;
4741        } catch (ClassCastException e) {
4742        }
4743        return false;
4744    }
4745
4746    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4747        if (!(pendingResult instanceof PendingIntentRecord)) {
4748            return false;
4749        }
4750        try {
4751            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4752            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4753                return true;
4754            }
4755            return false;
4756        } catch (ClassCastException e) {
4757        }
4758        return false;
4759    }
4760
4761    public void setProcessLimit(int max) {
4762        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4763                "setProcessLimit()");
4764        synchronized (this) {
4765            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4766            mProcessLimitOverride = max;
4767        }
4768        trimApplications();
4769    }
4770
4771    public int getProcessLimit() {
4772        synchronized (this) {
4773            return mProcessLimitOverride;
4774        }
4775    }
4776
4777    void foregroundTokenDied(ForegroundToken token) {
4778        synchronized (ActivityManagerService.this) {
4779            synchronized (mPidsSelfLocked) {
4780                ForegroundToken cur
4781                    = mForegroundProcesses.get(token.pid);
4782                if (cur != token) {
4783                    return;
4784                }
4785                mForegroundProcesses.remove(token.pid);
4786                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4787                if (pr == null) {
4788                    return;
4789                }
4790                pr.forcingToForeground = null;
4791                pr.foregroundServices = false;
4792            }
4793            updateOomAdjLocked();
4794        }
4795    }
4796
4797    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4798        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4799                "setProcessForeground()");
4800        synchronized(this) {
4801            boolean changed = false;
4802
4803            synchronized (mPidsSelfLocked) {
4804                ProcessRecord pr = mPidsSelfLocked.get(pid);
4805                if (pr == null && isForeground) {
4806                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4807                    return;
4808                }
4809                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4810                if (oldToken != null) {
4811                    oldToken.token.unlinkToDeath(oldToken, 0);
4812                    mForegroundProcesses.remove(pid);
4813                    if (pr != null) {
4814                        pr.forcingToForeground = null;
4815                    }
4816                    changed = true;
4817                }
4818                if (isForeground && token != null) {
4819                    ForegroundToken newToken = new ForegroundToken() {
4820                        public void binderDied() {
4821                            foregroundTokenDied(this);
4822                        }
4823                    };
4824                    newToken.pid = pid;
4825                    newToken.token = token;
4826                    try {
4827                        token.linkToDeath(newToken, 0);
4828                        mForegroundProcesses.put(pid, newToken);
4829                        pr.forcingToForeground = token;
4830                        changed = true;
4831                    } catch (RemoteException e) {
4832                        // If the process died while doing this, we will later
4833                        // do the cleanup with the process death link.
4834                    }
4835                }
4836            }
4837
4838            if (changed) {
4839                updateOomAdjLocked();
4840            }
4841        }
4842    }
4843
4844    // =========================================================
4845    // PERMISSIONS
4846    // =========================================================
4847
4848    static class PermissionController extends IPermissionController.Stub {
4849        ActivityManagerService mActivityManagerService;
4850        PermissionController(ActivityManagerService activityManagerService) {
4851            mActivityManagerService = activityManagerService;
4852        }
4853
4854        public boolean checkPermission(String permission, int pid, int uid) {
4855            return mActivityManagerService.checkPermission(permission, pid,
4856                    uid) == PackageManager.PERMISSION_GRANTED;
4857        }
4858    }
4859
4860    /**
4861     * This can be called with or without the global lock held.
4862     */
4863    int checkComponentPermission(String permission, int pid, int uid,
4864            int owningUid, boolean exported) {
4865        // We might be performing an operation on behalf of an indirect binder
4866        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4867        // client identity accordingly before proceeding.
4868        Identity tlsIdentity = sCallerIdentity.get();
4869        if (tlsIdentity != null) {
4870            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4871                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4872            uid = tlsIdentity.uid;
4873            pid = tlsIdentity.pid;
4874        }
4875
4876        if (pid == MY_PID) {
4877            return PackageManager.PERMISSION_GRANTED;
4878        }
4879
4880        return ActivityManager.checkComponentPermission(permission, uid,
4881                owningUid, exported);
4882    }
4883
4884    /**
4885     * As the only public entry point for permissions checking, this method
4886     * can enforce the semantic that requesting a check on a null global
4887     * permission is automatically denied.  (Internally a null permission
4888     * string is used when calling {@link #checkComponentPermission} in cases
4889     * when only uid-based security is needed.)
4890     *
4891     * This can be called with or without the global lock held.
4892     */
4893    public int checkPermission(String permission, int pid, int uid) {
4894        if (permission == null) {
4895            return PackageManager.PERMISSION_DENIED;
4896        }
4897        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4898    }
4899
4900    /**
4901     * Binder IPC calls go through the public entry point.
4902     * This can be called with or without the global lock held.
4903     */
4904    int checkCallingPermission(String permission) {
4905        return checkPermission(permission,
4906                Binder.getCallingPid(),
4907                UserHandle.getAppId(Binder.getCallingUid()));
4908    }
4909
4910    /**
4911     * This can be called with or without the global lock held.
4912     */
4913    void enforceCallingPermission(String permission, String func) {
4914        if (checkCallingPermission(permission)
4915                == PackageManager.PERMISSION_GRANTED) {
4916            return;
4917        }
4918
4919        String msg = "Permission Denial: " + func + " from pid="
4920                + Binder.getCallingPid()
4921                + ", uid=" + Binder.getCallingUid()
4922                + " requires " + permission;
4923        Slog.w(TAG, msg);
4924        throw new SecurityException(msg);
4925    }
4926
4927    /**
4928     * Determine if UID is holding permissions required to access {@link Uri} in
4929     * the given {@link ProviderInfo}. Final permission checking is always done
4930     * in {@link ContentProvider}.
4931     */
4932    private final boolean checkHoldingPermissionsLocked(
4933            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4934        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4935                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4936
4937        if (pi.applicationInfo.uid == uid) {
4938            return true;
4939        } else if (!pi.exported) {
4940            return false;
4941        }
4942
4943        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4944        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4945        try {
4946            // check if target holds top-level <provider> permissions
4947            if (!readMet && pi.readPermission != null
4948                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4949                readMet = true;
4950            }
4951            if (!writeMet && pi.writePermission != null
4952                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4953                writeMet = true;
4954            }
4955
4956            // track if unprotected read/write is allowed; any denied
4957            // <path-permission> below removes this ability
4958            boolean allowDefaultRead = pi.readPermission == null;
4959            boolean allowDefaultWrite = pi.writePermission == null;
4960
4961            // check if target holds any <path-permission> that match uri
4962            final PathPermission[] pps = pi.pathPermissions;
4963            if (pps != null) {
4964                final String path = uri.getPath();
4965                int i = pps.length;
4966                while (i > 0 && (!readMet || !writeMet)) {
4967                    i--;
4968                    PathPermission pp = pps[i];
4969                    if (pp.match(path)) {
4970                        if (!readMet) {
4971                            final String pprperm = pp.getReadPermission();
4972                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4973                                    + pprperm + " for " + pp.getPath()
4974                                    + ": match=" + pp.match(path)
4975                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4976                            if (pprperm != null) {
4977                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4978                                    readMet = true;
4979                                } else {
4980                                    allowDefaultRead = false;
4981                                }
4982                            }
4983                        }
4984                        if (!writeMet) {
4985                            final String ppwperm = pp.getWritePermission();
4986                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4987                                    + ppwperm + " for " + pp.getPath()
4988                                    + ": match=" + pp.match(path)
4989                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4990                            if (ppwperm != null) {
4991                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4992                                    writeMet = true;
4993                                } else {
4994                                    allowDefaultWrite = false;
4995                                }
4996                            }
4997                        }
4998                    }
4999                }
5000            }
5001
5002            // grant unprotected <provider> read/write, if not blocked by
5003            // <path-permission> above
5004            if (allowDefaultRead) readMet = true;
5005            if (allowDefaultWrite) writeMet = true;
5006
5007        } catch (RemoteException e) {
5008            return false;
5009        }
5010
5011        return readMet && writeMet;
5012    }
5013
5014    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5015            int modeFlags) {
5016        // Root gets to do everything.
5017        if (uid == 0) {
5018            return true;
5019        }
5020        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5021        if (perms == null) return false;
5022        UriPermission perm = perms.get(uri);
5023        if (perm == null) return false;
5024        return (modeFlags&perm.modeFlags) == modeFlags;
5025    }
5026
5027    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5028        enforceNotIsolatedCaller("checkUriPermission");
5029
5030        // Another redirected-binder-call permissions check as in
5031        // {@link checkComponentPermission}.
5032        Identity tlsIdentity = sCallerIdentity.get();
5033        if (tlsIdentity != null) {
5034            uid = tlsIdentity.uid;
5035            pid = tlsIdentity.pid;
5036        }
5037
5038        // Our own process gets to do everything.
5039        if (pid == MY_PID) {
5040            return PackageManager.PERMISSION_GRANTED;
5041        }
5042        synchronized(this) {
5043            return checkUriPermissionLocked(uri, uid, modeFlags)
5044                    ? PackageManager.PERMISSION_GRANTED
5045                    : PackageManager.PERMISSION_DENIED;
5046        }
5047    }
5048
5049    /**
5050     * Check if the targetPkg can be granted permission to access uri by
5051     * the callingUid using the given modeFlags.  Throws a security exception
5052     * if callingUid is not allowed to do this.  Returns the uid of the target
5053     * if the URI permission grant should be performed; returns -1 if it is not
5054     * needed (for example targetPkg already has permission to access the URI).
5055     * If you already know the uid of the target, you can supply it in
5056     * lastTargetUid else set that to -1.
5057     */
5058    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5059            Uri uri, int modeFlags, int lastTargetUid) {
5060        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5061                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5062        if (modeFlags == 0) {
5063            return -1;
5064        }
5065
5066        if (targetPkg != null) {
5067            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5068                    "Checking grant " + targetPkg + " permission to " + uri);
5069        }
5070
5071        final IPackageManager pm = AppGlobals.getPackageManager();
5072
5073        // If this is not a content: uri, we can't do anything with it.
5074        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5075            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5076                    "Can't grant URI permission for non-content URI: " + uri);
5077            return -1;
5078        }
5079
5080        String name = uri.getAuthority();
5081        ProviderInfo pi = null;
5082        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5083                UserHandle.getUserId(callingUid));
5084        if (cpr != null) {
5085            pi = cpr.info;
5086        } else {
5087            try {
5088                pi = pm.resolveContentProvider(name,
5089                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5090                        UserHandle.getUserId(callingUid));
5091            } catch (RemoteException ex) {
5092            }
5093        }
5094        if (pi == null) {
5095            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5096            return -1;
5097        }
5098
5099        int targetUid = lastTargetUid;
5100        if (targetUid < 0 && targetPkg != null) {
5101            try {
5102                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5103                if (targetUid < 0) {
5104                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5105                            "Can't grant URI permission no uid for: " + targetPkg);
5106                    return -1;
5107                }
5108            } catch (RemoteException ex) {
5109                return -1;
5110            }
5111        }
5112
5113        if (targetUid >= 0) {
5114            // First...  does the target actually need this permission?
5115            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5116                // No need to grant the target this permission.
5117                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5118                        "Target " + targetPkg + " already has full permission to " + uri);
5119                return -1;
5120            }
5121        } else {
5122            // First...  there is no target package, so can anyone access it?
5123            boolean allowed = pi.exported;
5124            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5125                if (pi.readPermission != null) {
5126                    allowed = false;
5127                }
5128            }
5129            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5130                if (pi.writePermission != null) {
5131                    allowed = false;
5132                }
5133            }
5134            if (allowed) {
5135                return -1;
5136            }
5137        }
5138
5139        // Second...  is the provider allowing granting of URI permissions?
5140        if (!pi.grantUriPermissions) {
5141            throw new SecurityException("Provider " + pi.packageName
5142                    + "/" + pi.name
5143                    + " does not allow granting of Uri permissions (uri "
5144                    + uri + ")");
5145        }
5146        if (pi.uriPermissionPatterns != null) {
5147            final int N = pi.uriPermissionPatterns.length;
5148            boolean allowed = false;
5149            for (int i=0; i<N; i++) {
5150                if (pi.uriPermissionPatterns[i] != null
5151                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5152                    allowed = true;
5153                    break;
5154                }
5155            }
5156            if (!allowed) {
5157                throw new SecurityException("Provider " + pi.packageName
5158                        + "/" + pi.name
5159                        + " does not allow granting of permission to path of Uri "
5160                        + uri);
5161            }
5162        }
5163
5164        // Third...  does the caller itself have permission to access
5165        // this uri?
5166        if (callingUid != Process.myUid()) {
5167            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5168                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5169                    throw new SecurityException("Uid " + callingUid
5170                            + " does not have permission to uri " + uri);
5171                }
5172            }
5173        }
5174
5175        return targetUid;
5176    }
5177
5178    public int checkGrantUriPermission(int callingUid, String targetPkg,
5179            Uri uri, int modeFlags) {
5180        enforceNotIsolatedCaller("checkGrantUriPermission");
5181        synchronized(this) {
5182            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5183        }
5184    }
5185
5186    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5187            Uri uri, int modeFlags, UriPermissionOwner owner) {
5188        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5189                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5190        if (modeFlags == 0) {
5191            return;
5192        }
5193
5194        // So here we are: the caller has the assumed permission
5195        // to the uri, and the target doesn't.  Let's now give this to
5196        // the target.
5197
5198        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5199                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5200
5201        HashMap<Uri, UriPermission> targetUris
5202                = mGrantedUriPermissions.get(targetUid);
5203        if (targetUris == null) {
5204            targetUris = new HashMap<Uri, UriPermission>();
5205            mGrantedUriPermissions.put(targetUid, targetUris);
5206        }
5207
5208        UriPermission perm = targetUris.get(uri);
5209        if (perm == null) {
5210            perm = new UriPermission(targetUid, uri);
5211            targetUris.put(uri, perm);
5212        }
5213
5214        perm.modeFlags |= modeFlags;
5215        if (owner == null) {
5216            perm.globalModeFlags |= modeFlags;
5217        } else {
5218            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5219                 perm.readOwners.add(owner);
5220                 owner.addReadPermission(perm);
5221            }
5222            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5223                 perm.writeOwners.add(owner);
5224                 owner.addWritePermission(perm);
5225            }
5226        }
5227    }
5228
5229    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5230            int modeFlags, UriPermissionOwner owner) {
5231        if (targetPkg == null) {
5232            throw new NullPointerException("targetPkg");
5233        }
5234
5235        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5236        if (targetUid < 0) {
5237            return;
5238        }
5239
5240        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5241    }
5242
5243    static class NeededUriGrants extends ArrayList<Uri> {
5244        final String targetPkg;
5245        final int targetUid;
5246        final int flags;
5247
5248        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5249            targetPkg = _targetPkg;
5250            targetUid = _targetUid;
5251            flags = _flags;
5252        }
5253    }
5254
5255    /**
5256     * Like checkGrantUriPermissionLocked, but takes an Intent.
5257     */
5258    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5259            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5260        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5261                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5262                + " clip=" + (intent != null ? intent.getClipData() : null)
5263                + " from " + intent + "; flags=0x"
5264                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5265
5266        if (targetPkg == null) {
5267            throw new NullPointerException("targetPkg");
5268        }
5269
5270        if (intent == null) {
5271            return null;
5272        }
5273        Uri data = intent.getData();
5274        ClipData clip = intent.getClipData();
5275        if (data == null && clip == null) {
5276            return null;
5277        }
5278        if (data != null) {
5279            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5280                mode, needed != null ? needed.targetUid : -1);
5281            if (target > 0) {
5282                if (needed == null) {
5283                    needed = new NeededUriGrants(targetPkg, target, mode);
5284                }
5285                needed.add(data);
5286            }
5287        }
5288        if (clip != null) {
5289            for (int i=0; i<clip.getItemCount(); i++) {
5290                Uri uri = clip.getItemAt(i).getUri();
5291                if (uri != null) {
5292                    int target = -1;
5293                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5294                            mode, needed != null ? needed.targetUid : -1);
5295                    if (target > 0) {
5296                        if (needed == null) {
5297                            needed = new NeededUriGrants(targetPkg, target, mode);
5298                        }
5299                        needed.add(uri);
5300                    }
5301                } else {
5302                    Intent clipIntent = clip.getItemAt(i).getIntent();
5303                    if (clipIntent != null) {
5304                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5305                                callingUid, targetPkg, clipIntent, mode, needed);
5306                        if (newNeeded != null) {
5307                            needed = newNeeded;
5308                        }
5309                    }
5310                }
5311            }
5312        }
5313
5314        return needed;
5315    }
5316
5317    /**
5318     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5319     */
5320    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5321            UriPermissionOwner owner) {
5322        if (needed != null) {
5323            for (int i=0; i<needed.size(); i++) {
5324                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5325                        needed.get(i), needed.flags, owner);
5326            }
5327        }
5328    }
5329
5330    void grantUriPermissionFromIntentLocked(int callingUid,
5331            String targetPkg, Intent intent, UriPermissionOwner owner) {
5332        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5333                intent, intent != null ? intent.getFlags() : 0, null);
5334        if (needed == null) {
5335            return;
5336        }
5337
5338        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5339    }
5340
5341    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5342            Uri uri, int modeFlags) {
5343        enforceNotIsolatedCaller("grantUriPermission");
5344        synchronized(this) {
5345            final ProcessRecord r = getRecordForAppLocked(caller);
5346            if (r == null) {
5347                throw new SecurityException("Unable to find app for caller "
5348                        + caller
5349                        + " when granting permission to uri " + uri);
5350            }
5351            if (targetPkg == null) {
5352                throw new IllegalArgumentException("null target");
5353            }
5354            if (uri == null) {
5355                throw new IllegalArgumentException("null uri");
5356            }
5357
5358            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5359                    null);
5360        }
5361    }
5362
5363    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5364        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5365                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5366            HashMap<Uri, UriPermission> perms
5367                    = mGrantedUriPermissions.get(perm.uid);
5368            if (perms != null) {
5369                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5370                        "Removing " + perm.uid + " permission to " + perm.uri);
5371                perms.remove(perm.uri);
5372                if (perms.size() == 0) {
5373                    mGrantedUriPermissions.remove(perm.uid);
5374                }
5375            }
5376        }
5377    }
5378
5379    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5380            int modeFlags) {
5381        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5382                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5383        if (modeFlags == 0) {
5384            return;
5385        }
5386
5387        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5388                "Revoking all granted permissions to " + uri);
5389
5390        final IPackageManager pm = AppGlobals.getPackageManager();
5391
5392        final String authority = uri.getAuthority();
5393        ProviderInfo pi = null;
5394        int userId = UserHandle.getUserId(callingUid);
5395        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5396        if (cpr != null) {
5397            pi = cpr.info;
5398        } else {
5399            try {
5400                pi = pm.resolveContentProvider(authority,
5401                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5402            } catch (RemoteException ex) {
5403            }
5404        }
5405        if (pi == null) {
5406            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5407            return;
5408        }
5409
5410        // Does the caller have this permission on the URI?
5411        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5412            // Right now, if you are not the original owner of the permission,
5413            // you are not allowed to revoke it.
5414            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5415                throw new SecurityException("Uid " + callingUid
5416                        + " does not have permission to uri " + uri);
5417            //}
5418        }
5419
5420        // Go through all of the permissions and remove any that match.
5421        final List<String> SEGMENTS = uri.getPathSegments();
5422        if (SEGMENTS != null) {
5423            final int NS = SEGMENTS.size();
5424            int N = mGrantedUriPermissions.size();
5425            for (int i=0; i<N; i++) {
5426                HashMap<Uri, UriPermission> perms
5427                        = mGrantedUriPermissions.valueAt(i);
5428                Iterator<UriPermission> it = perms.values().iterator();
5429            toploop:
5430                while (it.hasNext()) {
5431                    UriPermission perm = it.next();
5432                    Uri targetUri = perm.uri;
5433                    if (!authority.equals(targetUri.getAuthority())) {
5434                        continue;
5435                    }
5436                    List<String> targetSegments = targetUri.getPathSegments();
5437                    if (targetSegments == null) {
5438                        continue;
5439                    }
5440                    if (targetSegments.size() < NS) {
5441                        continue;
5442                    }
5443                    for (int j=0; j<NS; j++) {
5444                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5445                            continue toploop;
5446                        }
5447                    }
5448                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5449                            "Revoking " + perm.uid + " permission to " + perm.uri);
5450                    perm.clearModes(modeFlags);
5451                    if (perm.modeFlags == 0) {
5452                        it.remove();
5453                    }
5454                }
5455                if (perms.size() == 0) {
5456                    mGrantedUriPermissions.remove(
5457                            mGrantedUriPermissions.keyAt(i));
5458                    N--;
5459                    i--;
5460                }
5461            }
5462        }
5463    }
5464
5465    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5466            int modeFlags) {
5467        enforceNotIsolatedCaller("revokeUriPermission");
5468        synchronized(this) {
5469            final ProcessRecord r = getRecordForAppLocked(caller);
5470            if (r == null) {
5471                throw new SecurityException("Unable to find app for caller "
5472                        + caller
5473                        + " when revoking permission to uri " + uri);
5474            }
5475            if (uri == null) {
5476                Slog.w(TAG, "revokeUriPermission: null uri");
5477                return;
5478            }
5479
5480            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5481                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5482            if (modeFlags == 0) {
5483                return;
5484            }
5485
5486            final IPackageManager pm = AppGlobals.getPackageManager();
5487
5488            final String authority = uri.getAuthority();
5489            ProviderInfo pi = null;
5490            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5491            if (cpr != null) {
5492                pi = cpr.info;
5493            } else {
5494                try {
5495                    pi = pm.resolveContentProvider(authority,
5496                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5497                } catch (RemoteException ex) {
5498                }
5499            }
5500            if (pi == null) {
5501                Slog.w(TAG, "No content provider found for permission revoke: "
5502                        + uri.toSafeString());
5503                return;
5504            }
5505
5506            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5507        }
5508    }
5509
5510    @Override
5511    public IBinder newUriPermissionOwner(String name) {
5512        enforceNotIsolatedCaller("newUriPermissionOwner");
5513        synchronized(this) {
5514            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5515            return owner.getExternalTokenLocked();
5516        }
5517    }
5518
5519    @Override
5520    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5521            Uri uri, int modeFlags) {
5522        synchronized(this) {
5523            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5524            if (owner == null) {
5525                throw new IllegalArgumentException("Unknown owner: " + token);
5526            }
5527            if (fromUid != Binder.getCallingUid()) {
5528                if (Binder.getCallingUid() != Process.myUid()) {
5529                    // Only system code can grant URI permissions on behalf
5530                    // of other users.
5531                    throw new SecurityException("nice try");
5532                }
5533            }
5534            if (targetPkg == null) {
5535                throw new IllegalArgumentException("null target");
5536            }
5537            if (uri == null) {
5538                throw new IllegalArgumentException("null uri");
5539            }
5540
5541            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5542        }
5543    }
5544
5545    @Override
5546    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5547        synchronized(this) {
5548            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5549            if (owner == null) {
5550                throw new IllegalArgumentException("Unknown owner: " + token);
5551            }
5552
5553            if (uri == null) {
5554                owner.removeUriPermissionsLocked(mode);
5555            } else {
5556                owner.removeUriPermissionLocked(uri, mode);
5557            }
5558        }
5559    }
5560
5561    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5562        synchronized (this) {
5563            ProcessRecord app =
5564                who != null ? getRecordForAppLocked(who) : null;
5565            if (app == null) return;
5566
5567            Message msg = Message.obtain();
5568            msg.what = WAIT_FOR_DEBUGGER_MSG;
5569            msg.obj = app;
5570            msg.arg1 = waiting ? 1 : 0;
5571            mHandler.sendMessage(msg);
5572        }
5573    }
5574
5575    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5576        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5577        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5578        outInfo.availMem = Process.getFreeMemory();
5579        outInfo.totalMem = Process.getTotalMemory();
5580        outInfo.threshold = homeAppMem;
5581        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5582        outInfo.hiddenAppThreshold = hiddenAppMem;
5583        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5584                ProcessList.SERVICE_ADJ);
5585        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5586                ProcessList.VISIBLE_APP_ADJ);
5587        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5588                ProcessList.FOREGROUND_APP_ADJ);
5589    }
5590
5591    // =========================================================
5592    // TASK MANAGEMENT
5593    // =========================================================
5594
5595    public List getTasks(int maxNum, int flags,
5596                         IThumbnailReceiver receiver) {
5597        ArrayList list = new ArrayList();
5598
5599        PendingThumbnailsRecord pending = null;
5600        IApplicationThread topThumbnail = null;
5601        ActivityRecord topRecord = null;
5602
5603        synchronized(this) {
5604            if (localLOGV) Slog.v(
5605                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5606                + ", receiver=" + receiver);
5607
5608            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5609                    != PackageManager.PERMISSION_GRANTED) {
5610                if (receiver != null) {
5611                    // If the caller wants to wait for pending thumbnails,
5612                    // it ain't gonna get them.
5613                    try {
5614                        receiver.finished();
5615                    } catch (RemoteException ex) {
5616                    }
5617                }
5618                String msg = "Permission Denial: getTasks() from pid="
5619                        + Binder.getCallingPid()
5620                        + ", uid=" + Binder.getCallingUid()
5621                        + " requires " + android.Manifest.permission.GET_TASKS;
5622                Slog.w(TAG, msg);
5623                throw new SecurityException(msg);
5624            }
5625
5626            int pos = mMainStack.mHistory.size()-1;
5627            ActivityRecord next =
5628                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5629            ActivityRecord top = null;
5630            TaskRecord curTask = null;
5631            int numActivities = 0;
5632            int numRunning = 0;
5633            while (pos >= 0 && maxNum > 0) {
5634                final ActivityRecord r = next;
5635                pos--;
5636                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5637
5638                // Initialize state for next task if needed.
5639                if (top == null ||
5640                        (top.state == ActivityState.INITIALIZING
5641                            && top.task == r.task)) {
5642                    top = r;
5643                    curTask = r.task;
5644                    numActivities = numRunning = 0;
5645                }
5646
5647                // Add 'r' into the current task.
5648                numActivities++;
5649                if (r.app != null && r.app.thread != null) {
5650                    numRunning++;
5651                }
5652
5653                if (localLOGV) Slog.v(
5654                    TAG, r.intent.getComponent().flattenToShortString()
5655                    + ": task=" + r.task);
5656
5657                // If the next one is a different task, generate a new
5658                // TaskInfo entry for what we have.
5659                if (next == null || next.task != curTask) {
5660                    ActivityManager.RunningTaskInfo ci
5661                            = new ActivityManager.RunningTaskInfo();
5662                    ci.id = curTask.taskId;
5663                    ci.baseActivity = r.intent.getComponent();
5664                    ci.topActivity = top.intent.getComponent();
5665                    if (top.thumbHolder != null) {
5666                        ci.description = top.thumbHolder.lastDescription;
5667                    }
5668                    ci.numActivities = numActivities;
5669                    ci.numRunning = numRunning;
5670                    //System.out.println(
5671                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5672                    if (ci.thumbnail == null && receiver != null) {
5673                        if (localLOGV) Slog.v(
5674                            TAG, "State=" + top.state + "Idle=" + top.idle
5675                            + " app=" + top.app
5676                            + " thr=" + (top.app != null ? top.app.thread : null));
5677                        if (top.state == ActivityState.RESUMED
5678                                || top.state == ActivityState.PAUSING) {
5679                            if (top.idle && top.app != null
5680                                && top.app.thread != null) {
5681                                topRecord = top;
5682                                topThumbnail = top.app.thread;
5683                            } else {
5684                                top.thumbnailNeeded = true;
5685                            }
5686                        }
5687                        if (pending == null) {
5688                            pending = new PendingThumbnailsRecord(receiver);
5689                        }
5690                        pending.pendingRecords.add(top);
5691                    }
5692                    list.add(ci);
5693                    maxNum--;
5694                    top = null;
5695                }
5696            }
5697
5698            if (pending != null) {
5699                mPendingThumbnails.add(pending);
5700            }
5701        }
5702
5703        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5704
5705        if (topThumbnail != null) {
5706            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5707            try {
5708                topThumbnail.requestThumbnail(topRecord.appToken);
5709            } catch (Exception e) {
5710                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5711                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5712            }
5713        }
5714
5715        if (pending == null && receiver != null) {
5716            // In this case all thumbnails were available and the client
5717            // is being asked to be told when the remaining ones come in...
5718            // which is unusually, since the top-most currently running
5719            // activity should never have a canned thumbnail!  Oh well.
5720            try {
5721                receiver.finished();
5722            } catch (RemoteException ex) {
5723            }
5724        }
5725
5726        return list;
5727    }
5728
5729    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5730            int flags, int userId) {
5731        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5732                false, true, "getRecentTasks", null);
5733
5734        synchronized (this) {
5735            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5736                    "getRecentTasks()");
5737            final boolean detailed = checkCallingPermission(
5738                    android.Manifest.permission.GET_DETAILED_TASKS)
5739                    == PackageManager.PERMISSION_GRANTED;
5740
5741            IPackageManager pm = AppGlobals.getPackageManager();
5742
5743            final int N = mRecentTasks.size();
5744            ArrayList<ActivityManager.RecentTaskInfo> res
5745                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5746                            maxNum < N ? maxNum : N);
5747            for (int i=0; i<N && maxNum > 0; i++) {
5748                TaskRecord tr = mRecentTasks.get(i);
5749                // Only add calling user's recent tasks
5750                if (tr.userId != userId) continue;
5751                // Return the entry if desired by the caller.  We always return
5752                // the first entry, because callers always expect this to be the
5753                // foreground app.  We may filter others if the caller has
5754                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5755                // we should exclude the entry.
5756
5757                if (i == 0
5758                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5759                        || (tr.intent == null)
5760                        || ((tr.intent.getFlags()
5761                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5762                    ActivityManager.RecentTaskInfo rti
5763                            = new ActivityManager.RecentTaskInfo();
5764                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5765                    rti.persistentId = tr.taskId;
5766                    rti.baseIntent = new Intent(
5767                            tr.intent != null ? tr.intent : tr.affinityIntent);
5768                    if (!detailed) {
5769                        rti.baseIntent.replaceExtras((Bundle)null);
5770                    }
5771                    rti.origActivity = tr.origActivity;
5772                    rti.description = tr.lastDescription;
5773
5774                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5775                        // Check whether this activity is currently available.
5776                        try {
5777                            if (rti.origActivity != null) {
5778                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5779                                        == null) {
5780                                    continue;
5781                                }
5782                            } else if (rti.baseIntent != null) {
5783                                if (pm.queryIntentActivities(rti.baseIntent,
5784                                        null, 0, userId) == null) {
5785                                    continue;
5786                                }
5787                            }
5788                        } catch (RemoteException e) {
5789                            // Will never happen.
5790                        }
5791                    }
5792
5793                    res.add(rti);
5794                    maxNum--;
5795                }
5796            }
5797            return res;
5798        }
5799    }
5800
5801    private TaskRecord taskForIdLocked(int id) {
5802        final int N = mRecentTasks.size();
5803        for (int i=0; i<N; i++) {
5804            TaskRecord tr = mRecentTasks.get(i);
5805            if (tr.taskId == id) {
5806                return tr;
5807            }
5808        }
5809        return null;
5810    }
5811
5812    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5813        synchronized (this) {
5814            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5815                    "getTaskThumbnails()");
5816            TaskRecord tr = taskForIdLocked(id);
5817            if (tr != null) {
5818                return mMainStack.getTaskThumbnailsLocked(tr);
5819            }
5820        }
5821        return null;
5822    }
5823
5824    public Bitmap getTaskTopThumbnail(int id) {
5825        synchronized (this) {
5826            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5827                    "getTaskTopThumbnail()");
5828            TaskRecord tr = taskForIdLocked(id);
5829            if (tr != null) {
5830                return mMainStack.getTaskTopThumbnailLocked(tr);
5831            }
5832        }
5833        return null;
5834    }
5835
5836    public boolean removeSubTask(int taskId, int subTaskIndex) {
5837        synchronized (this) {
5838            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5839                    "removeSubTask()");
5840            long ident = Binder.clearCallingIdentity();
5841            try {
5842                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5843                        true) != null;
5844            } finally {
5845                Binder.restoreCallingIdentity(ident);
5846            }
5847        }
5848    }
5849
5850    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5851        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5852        Intent baseIntent = new Intent(
5853                tr.intent != null ? tr.intent : tr.affinityIntent);
5854        ComponentName component = baseIntent.getComponent();
5855        if (component == null) {
5856            Slog.w(TAG, "Now component for base intent of task: " + tr);
5857            return;
5858        }
5859
5860        // Find any running services associated with this app.
5861        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5862
5863        if (killProcesses) {
5864            // Find any running processes associated with this app.
5865            final String pkg = component.getPackageName();
5866            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5867            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5868            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5869                for (int i=0; i<uids.size(); i++) {
5870                    ProcessRecord proc = uids.valueAt(i);
5871                    if (proc.userId != tr.userId) {
5872                        continue;
5873                    }
5874                    if (!proc.pkgList.contains(pkg)) {
5875                        continue;
5876                    }
5877                    procs.add(proc);
5878                }
5879            }
5880
5881            // Kill the running processes.
5882            for (int i=0; i<procs.size(); i++) {
5883                ProcessRecord pr = procs.get(i);
5884                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5885                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5886                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5887                            pr.processName, pr.setAdj, "remove task");
5888                    pr.killedBackground = true;
5889                    Process.killProcessQuiet(pr.pid);
5890                } else {
5891                    pr.waitingToKill = "remove task";
5892                }
5893            }
5894        }
5895    }
5896
5897    public boolean removeTask(int taskId, int flags) {
5898        synchronized (this) {
5899            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5900                    "removeTask()");
5901            long ident = Binder.clearCallingIdentity();
5902            try {
5903                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5904                        false);
5905                if (r != null) {
5906                    mRecentTasks.remove(r.task);
5907                    cleanUpRemovedTaskLocked(r.task, flags);
5908                    return true;
5909                } else {
5910                    TaskRecord tr = null;
5911                    int i=0;
5912                    while (i < mRecentTasks.size()) {
5913                        TaskRecord t = mRecentTasks.get(i);
5914                        if (t.taskId == taskId) {
5915                            tr = t;
5916                            break;
5917                        }
5918                        i++;
5919                    }
5920                    if (tr != null) {
5921                        if (tr.numActivities <= 0) {
5922                            // Caller is just removing a recent task that is
5923                            // not actively running.  That is easy!
5924                            mRecentTasks.remove(i);
5925                            cleanUpRemovedTaskLocked(tr, flags);
5926                            return true;
5927                        } else {
5928                            Slog.w(TAG, "removeTask: task " + taskId
5929                                    + " does not have activities to remove, "
5930                                    + " but numActivities=" + tr.numActivities
5931                                    + ": " + tr);
5932                        }
5933                    }
5934                }
5935            } finally {
5936                Binder.restoreCallingIdentity(ident);
5937            }
5938        }
5939        return false;
5940    }
5941
5942    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5943        int j;
5944        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5945        TaskRecord jt = startTask;
5946
5947        // First look backwards
5948        for (j=startIndex-1; j>=0; j--) {
5949            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5950            if (r.task != jt) {
5951                jt = r.task;
5952                if (affinity.equals(jt.affinity)) {
5953                    return j;
5954                }
5955            }
5956        }
5957
5958        // Now look forwards
5959        final int N = mMainStack.mHistory.size();
5960        jt = startTask;
5961        for (j=startIndex+1; j<N; j++) {
5962            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5963            if (r.task != jt) {
5964                if (affinity.equals(jt.affinity)) {
5965                    return j;
5966                }
5967                jt = r.task;
5968            }
5969        }
5970
5971        // Might it be at the top?
5972        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5973            return N-1;
5974        }
5975
5976        return -1;
5977    }
5978
5979    /**
5980     * TODO: Add mController hook
5981     */
5982    public void moveTaskToFront(int task, int flags, Bundle options) {
5983        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5984                "moveTaskToFront()");
5985
5986        synchronized(this) {
5987            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5988                    Binder.getCallingUid(), "Task to front")) {
5989                ActivityOptions.abort(options);
5990                return;
5991            }
5992            final long origId = Binder.clearCallingIdentity();
5993            try {
5994                TaskRecord tr = taskForIdLocked(task);
5995                if (tr != null) {
5996                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5997                        mMainStack.mUserLeaving = true;
5998                    }
5999                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6000                        // Caller wants the home activity moved with it.  To accomplish this,
6001                        // we'll just move the home task to the top first.
6002                        mMainStack.moveHomeToFrontLocked();
6003                    }
6004                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6005                    return;
6006                }
6007                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6008                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6009                    if (hr.task.taskId == task) {
6010                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6011                            mMainStack.mUserLeaving = true;
6012                        }
6013                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6014                            // Caller wants the home activity moved with it.  To accomplish this,
6015                            // we'll just move the home task to the top first.
6016                            mMainStack.moveHomeToFrontLocked();
6017                        }
6018                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6019                        return;
6020                    }
6021                }
6022            } finally {
6023                Binder.restoreCallingIdentity(origId);
6024            }
6025            ActivityOptions.abort(options);
6026        }
6027    }
6028
6029    public void moveTaskToBack(int task) {
6030        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6031                "moveTaskToBack()");
6032
6033        synchronized(this) {
6034            if (mMainStack.mResumedActivity != null
6035                    && mMainStack.mResumedActivity.task.taskId == task) {
6036                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6037                        Binder.getCallingUid(), "Task to back")) {
6038                    return;
6039                }
6040            }
6041            final long origId = Binder.clearCallingIdentity();
6042            mMainStack.moveTaskToBackLocked(task, null);
6043            Binder.restoreCallingIdentity(origId);
6044        }
6045    }
6046
6047    /**
6048     * Moves an activity, and all of the other activities within the same task, to the bottom
6049     * of the history stack.  The activity's order within the task is unchanged.
6050     *
6051     * @param token A reference to the activity we wish to move
6052     * @param nonRoot If false then this only works if the activity is the root
6053     *                of a task; if true it will work for any activity in a task.
6054     * @return Returns true if the move completed, false if not.
6055     */
6056    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6057        enforceNotIsolatedCaller("moveActivityTaskToBack");
6058        synchronized(this) {
6059            final long origId = Binder.clearCallingIdentity();
6060            int taskId = getTaskForActivityLocked(token, !nonRoot);
6061            if (taskId >= 0) {
6062                return mMainStack.moveTaskToBackLocked(taskId, null);
6063            }
6064            Binder.restoreCallingIdentity(origId);
6065        }
6066        return false;
6067    }
6068
6069    public void moveTaskBackwards(int task) {
6070        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6071                "moveTaskBackwards()");
6072
6073        synchronized(this) {
6074            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6075                    Binder.getCallingUid(), "Task backwards")) {
6076                return;
6077            }
6078            final long origId = Binder.clearCallingIdentity();
6079            moveTaskBackwardsLocked(task);
6080            Binder.restoreCallingIdentity(origId);
6081        }
6082    }
6083
6084    private final void moveTaskBackwardsLocked(int task) {
6085        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6086    }
6087
6088    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6089        synchronized(this) {
6090            return getTaskForActivityLocked(token, onlyRoot);
6091        }
6092    }
6093
6094    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6095        final int N = mMainStack.mHistory.size();
6096        TaskRecord lastTask = null;
6097        for (int i=0; i<N; i++) {
6098            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6099            if (r.appToken == token) {
6100                if (!onlyRoot || lastTask != r.task) {
6101                    return r.task.taskId;
6102                }
6103                return -1;
6104            }
6105            lastTask = r.task;
6106        }
6107
6108        return -1;
6109    }
6110
6111    // =========================================================
6112    // THUMBNAILS
6113    // =========================================================
6114
6115    public void reportThumbnail(IBinder token,
6116            Bitmap thumbnail, CharSequence description) {
6117        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6118        final long origId = Binder.clearCallingIdentity();
6119        sendPendingThumbnail(null, token, thumbnail, description, true);
6120        Binder.restoreCallingIdentity(origId);
6121    }
6122
6123    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6124            Bitmap thumbnail, CharSequence description, boolean always) {
6125        TaskRecord task = null;
6126        ArrayList receivers = null;
6127
6128        //System.out.println("Send pending thumbnail: " + r);
6129
6130        synchronized(this) {
6131            if (r == null) {
6132                r = mMainStack.isInStackLocked(token);
6133                if (r == null) {
6134                    return;
6135                }
6136            }
6137            if (thumbnail == null && r.thumbHolder != null) {
6138                thumbnail = r.thumbHolder.lastThumbnail;
6139                description = r.thumbHolder.lastDescription;
6140            }
6141            if (thumbnail == null && !always) {
6142                // If there is no thumbnail, and this entry is not actually
6143                // going away, then abort for now and pick up the next
6144                // thumbnail we get.
6145                return;
6146            }
6147            task = r.task;
6148
6149            int N = mPendingThumbnails.size();
6150            int i=0;
6151            while (i<N) {
6152                PendingThumbnailsRecord pr =
6153                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6154                //System.out.println("Looking in " + pr.pendingRecords);
6155                if (pr.pendingRecords.remove(r)) {
6156                    if (receivers == null) {
6157                        receivers = new ArrayList();
6158                    }
6159                    receivers.add(pr);
6160                    if (pr.pendingRecords.size() == 0) {
6161                        pr.finished = true;
6162                        mPendingThumbnails.remove(i);
6163                        N--;
6164                        continue;
6165                    }
6166                }
6167                i++;
6168            }
6169        }
6170
6171        if (receivers != null) {
6172            final int N = receivers.size();
6173            for (int i=0; i<N; i++) {
6174                try {
6175                    PendingThumbnailsRecord pr =
6176                        (PendingThumbnailsRecord)receivers.get(i);
6177                    pr.receiver.newThumbnail(
6178                        task != null ? task.taskId : -1, thumbnail, description);
6179                    if (pr.finished) {
6180                        pr.receiver.finished();
6181                    }
6182                } catch (Exception e) {
6183                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6184                }
6185            }
6186        }
6187    }
6188
6189    // =========================================================
6190    // CONTENT PROVIDERS
6191    // =========================================================
6192
6193    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6194        List<ProviderInfo> providers = null;
6195        try {
6196            providers = AppGlobals.getPackageManager().
6197                queryContentProviders(app.processName, app.uid,
6198                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6199        } catch (RemoteException ex) {
6200        }
6201        if (DEBUG_MU)
6202            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6203        int userId = app.userId;
6204        if (providers != null) {
6205            int N = providers.size();
6206            for (int i=0; i<N; i++) {
6207                ProviderInfo cpi =
6208                    (ProviderInfo)providers.get(i);
6209                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6210                        cpi.name, cpi.flags);
6211                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6212                    // This is a singleton provider, but a user besides the
6213                    // default user is asking to initialize a process it runs
6214                    // in...  well, no, it doesn't actually run in this process,
6215                    // it runs in the process of the default user.  Get rid of it.
6216                    providers.remove(i);
6217                    N--;
6218                    continue;
6219                }
6220
6221                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6222                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6223                if (cpr == null) {
6224                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6225                    mProviderMap.putProviderByClass(comp, cpr);
6226                }
6227                if (DEBUG_MU)
6228                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6229                app.pubProviders.put(cpi.name, cpr);
6230                app.addPackage(cpi.applicationInfo.packageName);
6231                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6232            }
6233        }
6234        return providers;
6235    }
6236
6237    /**
6238     * Check if {@link ProcessRecord} has a possible chance at accessing the
6239     * given {@link ProviderInfo}. Final permission checking is always done
6240     * in {@link ContentProvider}.
6241     */
6242    private final String checkContentProviderPermissionLocked(
6243            ProviderInfo cpi, ProcessRecord r) {
6244        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6245        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6246        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6247                cpi.applicationInfo.uid, cpi.exported)
6248                == PackageManager.PERMISSION_GRANTED) {
6249            return null;
6250        }
6251        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6252                cpi.applicationInfo.uid, cpi.exported)
6253                == PackageManager.PERMISSION_GRANTED) {
6254            return null;
6255        }
6256
6257        PathPermission[] pps = cpi.pathPermissions;
6258        if (pps != null) {
6259            int i = pps.length;
6260            while (i > 0) {
6261                i--;
6262                PathPermission pp = pps[i];
6263                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6264                        cpi.applicationInfo.uid, cpi.exported)
6265                        == PackageManager.PERMISSION_GRANTED) {
6266                    return null;
6267                }
6268                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6269                        cpi.applicationInfo.uid, cpi.exported)
6270                        == PackageManager.PERMISSION_GRANTED) {
6271                    return null;
6272                }
6273            }
6274        }
6275
6276        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6277        if (perms != null) {
6278            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6279                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6280                    return null;
6281                }
6282            }
6283        }
6284
6285        String msg;
6286        if (!cpi.exported) {
6287            msg = "Permission Denial: opening provider " + cpi.name
6288                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6289                    + ", uid=" + callingUid + ") that is not exported from uid "
6290                    + cpi.applicationInfo.uid;
6291        } else {
6292            msg = "Permission Denial: opening provider " + cpi.name
6293                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6294                    + ", uid=" + callingUid + ") requires "
6295                    + cpi.readPermission + " or " + cpi.writePermission;
6296        }
6297        Slog.w(TAG, msg);
6298        return msg;
6299    }
6300
6301    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6302            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6303        if (r != null) {
6304            for (int i=0; i<r.conProviders.size(); i++) {
6305                ContentProviderConnection conn = r.conProviders.get(i);
6306                if (conn.provider == cpr) {
6307                    if (DEBUG_PROVIDER) Slog.v(TAG,
6308                            "Adding provider requested by "
6309                            + r.processName + " from process "
6310                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6311                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6312                    if (stable) {
6313                        conn.stableCount++;
6314                        conn.numStableIncs++;
6315                    } else {
6316                        conn.unstableCount++;
6317                        conn.numUnstableIncs++;
6318                    }
6319                    return conn;
6320                }
6321            }
6322            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6323            if (stable) {
6324                conn.stableCount = 1;
6325                conn.numStableIncs = 1;
6326            } else {
6327                conn.unstableCount = 1;
6328                conn.numUnstableIncs = 1;
6329            }
6330            cpr.connections.add(conn);
6331            r.conProviders.add(conn);
6332            return conn;
6333        }
6334        cpr.addExternalProcessHandleLocked(externalProcessToken);
6335        return null;
6336    }
6337
6338    boolean decProviderCountLocked(ContentProviderConnection conn,
6339            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6340        if (conn != null) {
6341            cpr = conn.provider;
6342            if (DEBUG_PROVIDER) Slog.v(TAG,
6343                    "Removing provider requested by "
6344                    + conn.client.processName + " from process "
6345                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6346                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6347            if (stable) {
6348                conn.stableCount--;
6349            } else {
6350                conn.unstableCount--;
6351            }
6352            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6353                cpr.connections.remove(conn);
6354                conn.client.conProviders.remove(conn);
6355                return true;
6356            }
6357            return false;
6358        }
6359        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6360        return false;
6361    }
6362
6363    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6364            String name, IBinder token, boolean stable, int userId) {
6365        ContentProviderRecord cpr;
6366        ContentProviderConnection conn = null;
6367        ProviderInfo cpi = null;
6368
6369        synchronized(this) {
6370            ProcessRecord r = null;
6371            if (caller != null) {
6372                r = getRecordForAppLocked(caller);
6373                if (r == null) {
6374                    throw new SecurityException(
6375                            "Unable to find app for caller " + caller
6376                          + " (pid=" + Binder.getCallingPid()
6377                          + ") when getting content provider " + name);
6378                }
6379            }
6380
6381            // First check if this content provider has been published...
6382            cpr = mProviderMap.getProviderByName(name, userId);
6383            boolean providerRunning = cpr != null;
6384            if (providerRunning) {
6385                cpi = cpr.info;
6386                String msg;
6387                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6388                    throw new SecurityException(msg);
6389                }
6390
6391                if (r != null && cpr.canRunHere(r)) {
6392                    // This provider has been published or is in the process
6393                    // of being published...  but it is also allowed to run
6394                    // in the caller's process, so don't make a connection
6395                    // and just let the caller instantiate its own instance.
6396                    ContentProviderHolder holder = cpr.newHolder(null);
6397                    // don't give caller the provider object, it needs
6398                    // to make its own.
6399                    holder.provider = null;
6400                    return holder;
6401                }
6402
6403                final long origId = Binder.clearCallingIdentity();
6404
6405                // In this case the provider instance already exists, so we can
6406                // return it right away.
6407                conn = incProviderCountLocked(r, cpr, token, stable);
6408                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6409                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6410                        // If this is a perceptible app accessing the provider,
6411                        // make sure to count it as being accessed and thus
6412                        // back up on the LRU list.  This is good because
6413                        // content providers are often expensive to start.
6414                        updateLruProcessLocked(cpr.proc, false);
6415                    }
6416                }
6417
6418                if (cpr.proc != null) {
6419                    if (false) {
6420                        if (cpr.name.flattenToShortString().equals(
6421                                "com.android.providers.calendar/.CalendarProvider2")) {
6422                            Slog.v(TAG, "****************** KILLING "
6423                                + cpr.name.flattenToShortString());
6424                            Process.killProcess(cpr.proc.pid);
6425                        }
6426                    }
6427                    boolean success = updateOomAdjLocked(cpr.proc);
6428                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6429                    // NOTE: there is still a race here where a signal could be
6430                    // pending on the process even though we managed to update its
6431                    // adj level.  Not sure what to do about this, but at least
6432                    // the race is now smaller.
6433                    if (!success) {
6434                        // Uh oh...  it looks like the provider's process
6435                        // has been killed on us.  We need to wait for a new
6436                        // process to be started, and make sure its death
6437                        // doesn't kill our process.
6438                        Slog.i(TAG,
6439                                "Existing provider " + cpr.name.flattenToShortString()
6440                                + " is crashing; detaching " + r);
6441                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6442                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6443                        if (!lastRef) {
6444                            // This wasn't the last ref our process had on
6445                            // the provider...  we have now been killed, bail.
6446                            return null;
6447                        }
6448                        providerRunning = false;
6449                        conn = null;
6450                    }
6451                }
6452
6453                Binder.restoreCallingIdentity(origId);
6454            }
6455
6456            boolean singleton;
6457            if (!providerRunning) {
6458                try {
6459                    cpi = AppGlobals.getPackageManager().
6460                        resolveContentProvider(name,
6461                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6462                } catch (RemoteException ex) {
6463                }
6464                if (cpi == null) {
6465                    return null;
6466                }
6467                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6468                        cpi.name, cpi.flags);
6469                if (singleton) {
6470                    userId = 0;
6471                }
6472                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6473
6474                String msg;
6475                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6476                    throw new SecurityException(msg);
6477                }
6478
6479                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6480                        && !cpi.processName.equals("system")) {
6481                    // If this content provider does not run in the system
6482                    // process, and the system is not yet ready to run other
6483                    // processes, then fail fast instead of hanging.
6484                    throw new IllegalArgumentException(
6485                            "Attempt to launch content provider before system ready");
6486                }
6487
6488                // Make sure that the user who owns this provider is started.  If not,
6489                // we don't want to allow it to run.
6490                if (mStartedUsers.get(userId) == null) {
6491                    Slog.w(TAG, "Unable to launch app "
6492                            + cpi.applicationInfo.packageName + "/"
6493                            + cpi.applicationInfo.uid + " for provider "
6494                            + name + ": user " + userId + " is stopped");
6495                    return null;
6496                }
6497
6498                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6499                cpr = mProviderMap.getProviderByClass(comp, userId);
6500                final boolean firstClass = cpr == null;
6501                if (firstClass) {
6502                    try {
6503                        ApplicationInfo ai =
6504                            AppGlobals.getPackageManager().
6505                                getApplicationInfo(
6506                                        cpi.applicationInfo.packageName,
6507                                        STOCK_PM_FLAGS, userId);
6508                        if (ai == null) {
6509                            Slog.w(TAG, "No package info for content provider "
6510                                    + cpi.name);
6511                            return null;
6512                        }
6513                        ai = getAppInfoForUser(ai, userId);
6514                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6515                    } catch (RemoteException ex) {
6516                        // pm is in same process, this will never happen.
6517                    }
6518                }
6519
6520                if (r != null && cpr.canRunHere(r)) {
6521                    // If this is a multiprocess provider, then just return its
6522                    // info and allow the caller to instantiate it.  Only do
6523                    // this if the provider is the same user as the caller's
6524                    // process, or can run as root (so can be in any process).
6525                    return cpr.newHolder(null);
6526                }
6527
6528                if (DEBUG_PROVIDER) {
6529                    RuntimeException e = new RuntimeException("here");
6530                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6531                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6532                }
6533
6534                // This is single process, and our app is now connecting to it.
6535                // See if we are already in the process of launching this
6536                // provider.
6537                final int N = mLaunchingProviders.size();
6538                int i;
6539                for (i=0; i<N; i++) {
6540                    if (mLaunchingProviders.get(i) == cpr) {
6541                        break;
6542                    }
6543                }
6544
6545                // If the provider is not already being launched, then get it
6546                // started.
6547                if (i >= N) {
6548                    final long origId = Binder.clearCallingIdentity();
6549
6550                    try {
6551                        // Content provider is now in use, its package can't be stopped.
6552                        try {
6553                            AppGlobals.getPackageManager().setPackageStoppedState(
6554                                    cpr.appInfo.packageName, false, userId);
6555                        } catch (RemoteException e) {
6556                        } catch (IllegalArgumentException e) {
6557                            Slog.w(TAG, "Failed trying to unstop package "
6558                                    + cpr.appInfo.packageName + ": " + e);
6559                        }
6560
6561                        ProcessRecord proc = startProcessLocked(cpi.processName,
6562                                cpr.appInfo, false, 0, "content provider",
6563                                new ComponentName(cpi.applicationInfo.packageName,
6564                                        cpi.name), false, false);
6565                        if (proc == null) {
6566                            Slog.w(TAG, "Unable to launch app "
6567                                    + cpi.applicationInfo.packageName + "/"
6568                                    + cpi.applicationInfo.uid + " for provider "
6569                                    + name + ": process is bad");
6570                            return null;
6571                        }
6572                        cpr.launchingApp = proc;
6573                        mLaunchingProviders.add(cpr);
6574                    } finally {
6575                        Binder.restoreCallingIdentity(origId);
6576                    }
6577                }
6578
6579                // Make sure the provider is published (the same provider class
6580                // may be published under multiple names).
6581                if (firstClass) {
6582                    mProviderMap.putProviderByClass(comp, cpr);
6583                }
6584
6585                mProviderMap.putProviderByName(name, cpr);
6586                conn = incProviderCountLocked(r, cpr, token, stable);
6587                if (conn != null) {
6588                    conn.waiting = true;
6589                }
6590            }
6591        }
6592
6593        // Wait for the provider to be published...
6594        synchronized (cpr) {
6595            while (cpr.provider == null) {
6596                if (cpr.launchingApp == null) {
6597                    Slog.w(TAG, "Unable to launch app "
6598                            + cpi.applicationInfo.packageName + "/"
6599                            + cpi.applicationInfo.uid + " for provider "
6600                            + name + ": launching app became null");
6601                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6602                            UserHandle.getUserId(cpi.applicationInfo.uid),
6603                            cpi.applicationInfo.packageName,
6604                            cpi.applicationInfo.uid, name);
6605                    return null;
6606                }
6607                try {
6608                    if (DEBUG_MU) {
6609                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6610                                + cpr.launchingApp);
6611                    }
6612                    if (conn != null) {
6613                        conn.waiting = true;
6614                    }
6615                    cpr.wait();
6616                } catch (InterruptedException ex) {
6617                } finally {
6618                    if (conn != null) {
6619                        conn.waiting = false;
6620                    }
6621                }
6622            }
6623        }
6624        return cpr != null ? cpr.newHolder(conn) : null;
6625    }
6626
6627    public final ContentProviderHolder getContentProvider(
6628            IApplicationThread caller, String name, int userId, boolean stable) {
6629        enforceNotIsolatedCaller("getContentProvider");
6630        if (caller == null) {
6631            String msg = "null IApplicationThread when getting content provider "
6632                    + name;
6633            Slog.w(TAG, msg);
6634            throw new SecurityException(msg);
6635        }
6636
6637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6638                false, true, "getContentProvider", null);
6639        return getContentProviderImpl(caller, name, null, stable, userId);
6640    }
6641
6642    public ContentProviderHolder getContentProviderExternal(
6643            String name, int userId, IBinder token) {
6644        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6645            "Do not have permission in call getContentProviderExternal()");
6646        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6647                false, true, "getContentProvider", null);
6648        return getContentProviderExternalUnchecked(name, token, userId);
6649    }
6650
6651    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6652            IBinder token, int userId) {
6653        return getContentProviderImpl(null, name, token, true, userId);
6654    }
6655
6656    /**
6657     * Drop a content provider from a ProcessRecord's bookkeeping
6658     * @param cpr
6659     */
6660    public void removeContentProvider(IBinder connection, boolean stable) {
6661        enforceNotIsolatedCaller("removeContentProvider");
6662        synchronized (this) {
6663            ContentProviderConnection conn;
6664            try {
6665                conn = (ContentProviderConnection)connection;
6666            } catch (ClassCastException e) {
6667                String msg ="removeContentProvider: " + connection
6668                        + " not a ContentProviderConnection";
6669                Slog.w(TAG, msg);
6670                throw new IllegalArgumentException(msg);
6671            }
6672            if (conn == null) {
6673                throw new NullPointerException("connection is null");
6674            }
6675            if (decProviderCountLocked(conn, null, null, stable)) {
6676                updateOomAdjLocked();
6677            }
6678        }
6679    }
6680
6681    public void removeContentProviderExternal(String name, IBinder token) {
6682        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6683            "Do not have permission in call removeContentProviderExternal()");
6684        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6685    }
6686
6687    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6688        synchronized (this) {
6689            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6690            if(cpr == null) {
6691                //remove from mProvidersByClass
6692                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6693                return;
6694            }
6695
6696            //update content provider record entry info
6697            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6698            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6699            if (localCpr.hasExternalProcessHandles()) {
6700                if (localCpr.removeExternalProcessHandleLocked(token)) {
6701                    updateOomAdjLocked();
6702                } else {
6703                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6704                            + " with no external reference for token: "
6705                            + token + ".");
6706                }
6707            } else {
6708                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6709                        + " with no external references.");
6710            }
6711        }
6712    }
6713
6714    public final void publishContentProviders(IApplicationThread caller,
6715            List<ContentProviderHolder> providers) {
6716        if (providers == null) {
6717            return;
6718        }
6719
6720        enforceNotIsolatedCaller("publishContentProviders");
6721        synchronized (this) {
6722            final ProcessRecord r = getRecordForAppLocked(caller);
6723            if (DEBUG_MU)
6724                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6725            if (r == null) {
6726                throw new SecurityException(
6727                        "Unable to find app for caller " + caller
6728                      + " (pid=" + Binder.getCallingPid()
6729                      + ") when publishing content providers");
6730            }
6731
6732            final long origId = Binder.clearCallingIdentity();
6733
6734            final int N = providers.size();
6735            for (int i=0; i<N; i++) {
6736                ContentProviderHolder src = providers.get(i);
6737                if (src == null || src.info == null || src.provider == null) {
6738                    continue;
6739                }
6740                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6741                if (DEBUG_MU)
6742                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6743                if (dst != null) {
6744                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6745                    mProviderMap.putProviderByClass(comp, dst);
6746                    String names[] = dst.info.authority.split(";");
6747                    for (int j = 0; j < names.length; j++) {
6748                        mProviderMap.putProviderByName(names[j], dst);
6749                    }
6750
6751                    int NL = mLaunchingProviders.size();
6752                    int j;
6753                    for (j=0; j<NL; j++) {
6754                        if (mLaunchingProviders.get(j) == dst) {
6755                            mLaunchingProviders.remove(j);
6756                            j--;
6757                            NL--;
6758                        }
6759                    }
6760                    synchronized (dst) {
6761                        dst.provider = src.provider;
6762                        dst.proc = r;
6763                        dst.notifyAll();
6764                    }
6765                    updateOomAdjLocked(r);
6766                }
6767            }
6768
6769            Binder.restoreCallingIdentity(origId);
6770        }
6771    }
6772
6773    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6774        ContentProviderConnection conn;
6775        try {
6776            conn = (ContentProviderConnection)connection;
6777        } catch (ClassCastException e) {
6778            String msg ="refContentProvider: " + connection
6779                    + " not a ContentProviderConnection";
6780            Slog.w(TAG, msg);
6781            throw new IllegalArgumentException(msg);
6782        }
6783        if (conn == null) {
6784            throw new NullPointerException("connection is null");
6785        }
6786
6787        synchronized (this) {
6788            if (stable > 0) {
6789                conn.numStableIncs += stable;
6790            }
6791            stable = conn.stableCount + stable;
6792            if (stable < 0) {
6793                throw new IllegalStateException("stableCount < 0: " + stable);
6794            }
6795
6796            if (unstable > 0) {
6797                conn.numUnstableIncs += unstable;
6798            }
6799            unstable = conn.unstableCount + unstable;
6800            if (unstable < 0) {
6801                throw new IllegalStateException("unstableCount < 0: " + unstable);
6802            }
6803
6804            if ((stable+unstable) <= 0) {
6805                throw new IllegalStateException("ref counts can't go to zero here: stable="
6806                        + stable + " unstable=" + unstable);
6807            }
6808            conn.stableCount = stable;
6809            conn.unstableCount = unstable;
6810            return !conn.dead;
6811        }
6812    }
6813
6814    public void unstableProviderDied(IBinder connection) {
6815        ContentProviderConnection conn;
6816        try {
6817            conn = (ContentProviderConnection)connection;
6818        } catch (ClassCastException e) {
6819            String msg ="refContentProvider: " + connection
6820                    + " not a ContentProviderConnection";
6821            Slog.w(TAG, msg);
6822            throw new IllegalArgumentException(msg);
6823        }
6824        if (conn == null) {
6825            throw new NullPointerException("connection is null");
6826        }
6827
6828        // Safely retrieve the content provider associated with the connection.
6829        IContentProvider provider;
6830        synchronized (this) {
6831            provider = conn.provider.provider;
6832        }
6833
6834        if (provider == null) {
6835            // Um, yeah, we're way ahead of you.
6836            return;
6837        }
6838
6839        // Make sure the caller is being honest with us.
6840        if (provider.asBinder().pingBinder()) {
6841            // Er, no, still looks good to us.
6842            synchronized (this) {
6843                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6844                        + " says " + conn + " died, but we don't agree");
6845                return;
6846            }
6847        }
6848
6849        // Well look at that!  It's dead!
6850        synchronized (this) {
6851            if (conn.provider.provider != provider) {
6852                // But something changed...  good enough.
6853                return;
6854            }
6855
6856            ProcessRecord proc = conn.provider.proc;
6857            if (proc == null || proc.thread == null) {
6858                // Seems like the process is already cleaned up.
6859                return;
6860            }
6861
6862            // As far as we're concerned, this is just like receiving a
6863            // death notification...  just a bit prematurely.
6864            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6865                    + ") early provider death");
6866            final long ident = Binder.clearCallingIdentity();
6867            try {
6868                appDiedLocked(proc, proc.pid, proc.thread);
6869            } finally {
6870                Binder.restoreCallingIdentity(ident);
6871            }
6872        }
6873    }
6874
6875    public static final void installSystemProviders() {
6876        List<ProviderInfo> providers;
6877        synchronized (mSelf) {
6878            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6879            providers = mSelf.generateApplicationProvidersLocked(app);
6880            if (providers != null) {
6881                for (int i=providers.size()-1; i>=0; i--) {
6882                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6883                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6884                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6885                                + ": not system .apk");
6886                        providers.remove(i);
6887                    }
6888                }
6889            }
6890        }
6891        if (providers != null) {
6892            mSystemThread.installSystemProviders(providers);
6893        }
6894
6895        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6896
6897        mSelf.mUsageStatsService.monitorPackages();
6898    }
6899
6900    /**
6901     * Allows app to retrieve the MIME type of a URI without having permission
6902     * to access its content provider.
6903     *
6904     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6905     *
6906     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6907     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6908     */
6909    public String getProviderMimeType(Uri uri, int userId) {
6910        enforceNotIsolatedCaller("getProviderMimeType");
6911        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6912                userId, false, true, "getProviderMimeType", null);
6913        final String name = uri.getAuthority();
6914        final long ident = Binder.clearCallingIdentity();
6915        ContentProviderHolder holder = null;
6916
6917        try {
6918            holder = getContentProviderExternalUnchecked(name, null, userId);
6919            if (holder != null) {
6920                return holder.provider.getType(uri);
6921            }
6922        } catch (RemoteException e) {
6923            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6924            return null;
6925        } finally {
6926            if (holder != null) {
6927                removeContentProviderExternalUnchecked(name, null, userId);
6928            }
6929            Binder.restoreCallingIdentity(ident);
6930        }
6931
6932        return null;
6933    }
6934
6935    // =========================================================
6936    // GLOBAL MANAGEMENT
6937    // =========================================================
6938
6939    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6940            ApplicationInfo info, String customProcess, boolean isolated) {
6941        String proc = customProcess != null ? customProcess : info.processName;
6942        BatteryStatsImpl.Uid.Proc ps = null;
6943        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6944        int uid = info.uid;
6945        if (isolated) {
6946            int userId = UserHandle.getUserId(uid);
6947            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6948            uid = 0;
6949            while (true) {
6950                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6951                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6952                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6953                }
6954                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6955                mNextIsolatedProcessUid++;
6956                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6957                    // No process for this uid, use it.
6958                    break;
6959                }
6960                stepsLeft--;
6961                if (stepsLeft <= 0) {
6962                    return null;
6963                }
6964            }
6965        }
6966        synchronized (stats) {
6967            ps = stats.getProcessStatsLocked(info.uid, proc);
6968        }
6969        return new ProcessRecord(ps, thread, info, proc, uid);
6970    }
6971
6972    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6973        ProcessRecord app;
6974        if (!isolated) {
6975            app = getProcessRecordLocked(info.processName, info.uid);
6976        } else {
6977            app = null;
6978        }
6979
6980        if (app == null) {
6981            app = newProcessRecordLocked(null, info, null, isolated);
6982            mProcessNames.put(info.processName, app.uid, app);
6983            if (isolated) {
6984                mIsolatedProcesses.put(app.uid, app);
6985            }
6986            updateLruProcessLocked(app, true);
6987        }
6988
6989        // This package really, really can not be stopped.
6990        try {
6991            AppGlobals.getPackageManager().setPackageStoppedState(
6992                    info.packageName, false, UserHandle.getUserId(app.uid));
6993        } catch (RemoteException e) {
6994        } catch (IllegalArgumentException e) {
6995            Slog.w(TAG, "Failed trying to unstop package "
6996                    + info.packageName + ": " + e);
6997        }
6998
6999        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7000                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7001            app.persistent = true;
7002            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7003        }
7004        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7005            mPersistentStartingProcesses.add(app);
7006            startProcessLocked(app, "added application", app.processName);
7007        }
7008
7009        return app;
7010    }
7011
7012    public void unhandledBack() {
7013        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7014                "unhandledBack()");
7015
7016        synchronized(this) {
7017            int count = mMainStack.mHistory.size();
7018            if (DEBUG_SWITCH) Slog.d(
7019                TAG, "Performing unhandledBack(): stack size = " + count);
7020            if (count > 1) {
7021                final long origId = Binder.clearCallingIdentity();
7022                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7023                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7024                Binder.restoreCallingIdentity(origId);
7025            }
7026        }
7027    }
7028
7029    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7030        enforceNotIsolatedCaller("openContentUri");
7031        final int userId = UserHandle.getCallingUserId();
7032        String name = uri.getAuthority();
7033        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7034        ParcelFileDescriptor pfd = null;
7035        if (cph != null) {
7036            // We record the binder invoker's uid in thread-local storage before
7037            // going to the content provider to open the file.  Later, in the code
7038            // that handles all permissions checks, we look for this uid and use
7039            // that rather than the Activity Manager's own uid.  The effect is that
7040            // we do the check against the caller's permissions even though it looks
7041            // to the content provider like the Activity Manager itself is making
7042            // the request.
7043            sCallerIdentity.set(new Identity(
7044                    Binder.getCallingPid(), Binder.getCallingUid()));
7045            try {
7046                pfd = cph.provider.openFile(uri, "r");
7047            } catch (FileNotFoundException e) {
7048                // do nothing; pfd will be returned null
7049            } finally {
7050                // Ensure that whatever happens, we clean up the identity state
7051                sCallerIdentity.remove();
7052            }
7053
7054            // We've got the fd now, so we're done with the provider.
7055            removeContentProviderExternalUnchecked(name, null, userId);
7056        } else {
7057            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7058        }
7059        return pfd;
7060    }
7061
7062    // Actually is sleeping or shutting down or whatever else in the future
7063    // is an inactive state.
7064    public boolean isSleeping() {
7065        return mSleeping || mShuttingDown;
7066    }
7067
7068    public void goingToSleep() {
7069        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7070                != PackageManager.PERMISSION_GRANTED) {
7071            throw new SecurityException("Requires permission "
7072                    + android.Manifest.permission.DEVICE_POWER);
7073        }
7074
7075        synchronized(this) {
7076            mWentToSleep = true;
7077            updateEventDispatchingLocked();
7078
7079            if (!mSleeping) {
7080                mSleeping = true;
7081                mMainStack.stopIfSleepingLocked();
7082
7083                // Initialize the wake times of all processes.
7084                checkExcessivePowerUsageLocked(false);
7085                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7086                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7087                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7088            }
7089        }
7090    }
7091
7092    public boolean shutdown(int timeout) {
7093        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7094                != PackageManager.PERMISSION_GRANTED) {
7095            throw new SecurityException("Requires permission "
7096                    + android.Manifest.permission.SHUTDOWN);
7097        }
7098
7099        boolean timedout = false;
7100
7101        synchronized(this) {
7102            mShuttingDown = true;
7103            updateEventDispatchingLocked();
7104
7105            if (mMainStack.mResumedActivity != null) {
7106                mMainStack.stopIfSleepingLocked();
7107                final long endTime = System.currentTimeMillis() + timeout;
7108                while (mMainStack.mResumedActivity != null
7109                        || mMainStack.mPausingActivity != null) {
7110                    long delay = endTime - System.currentTimeMillis();
7111                    if (delay <= 0) {
7112                        Slog.w(TAG, "Activity manager shutdown timed out");
7113                        timedout = true;
7114                        break;
7115                    }
7116                    try {
7117                        this.wait();
7118                    } catch (InterruptedException e) {
7119                    }
7120                }
7121            }
7122        }
7123
7124        mUsageStatsService.shutdown();
7125        mBatteryStatsService.shutdown();
7126
7127        return timedout;
7128    }
7129
7130    public final void activitySlept(IBinder token) {
7131        if (localLOGV) Slog.v(
7132            TAG, "Activity slept: token=" + token);
7133
7134        ActivityRecord r = null;
7135
7136        final long origId = Binder.clearCallingIdentity();
7137
7138        synchronized (this) {
7139            r = mMainStack.isInStackLocked(token);
7140            if (r != null) {
7141                mMainStack.activitySleptLocked(r);
7142            }
7143        }
7144
7145        Binder.restoreCallingIdentity(origId);
7146    }
7147
7148    private void comeOutOfSleepIfNeededLocked() {
7149        if (!mWentToSleep && !mLockScreenShown) {
7150            if (mSleeping) {
7151                mSleeping = false;
7152                mMainStack.awakeFromSleepingLocked();
7153                mMainStack.resumeTopActivityLocked(null);
7154            }
7155        }
7156    }
7157
7158    public void wakingUp() {
7159        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7160                != PackageManager.PERMISSION_GRANTED) {
7161            throw new SecurityException("Requires permission "
7162                    + android.Manifest.permission.DEVICE_POWER);
7163        }
7164
7165        synchronized(this) {
7166            mWentToSleep = false;
7167            updateEventDispatchingLocked();
7168            comeOutOfSleepIfNeededLocked();
7169        }
7170    }
7171
7172    private void updateEventDispatchingLocked() {
7173        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7174    }
7175
7176    public void setLockScreenShown(boolean shown) {
7177        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7178                != PackageManager.PERMISSION_GRANTED) {
7179            throw new SecurityException("Requires permission "
7180                    + android.Manifest.permission.DEVICE_POWER);
7181        }
7182
7183        synchronized(this) {
7184            mLockScreenShown = shown;
7185            comeOutOfSleepIfNeededLocked();
7186        }
7187    }
7188
7189    public void stopAppSwitches() {
7190        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7191                != PackageManager.PERMISSION_GRANTED) {
7192            throw new SecurityException("Requires permission "
7193                    + android.Manifest.permission.STOP_APP_SWITCHES);
7194        }
7195
7196        synchronized(this) {
7197            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7198                    + APP_SWITCH_DELAY_TIME;
7199            mDidAppSwitch = false;
7200            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7201            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7202            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7203        }
7204    }
7205
7206    public void resumeAppSwitches() {
7207        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7208                != PackageManager.PERMISSION_GRANTED) {
7209            throw new SecurityException("Requires permission "
7210                    + android.Manifest.permission.STOP_APP_SWITCHES);
7211        }
7212
7213        synchronized(this) {
7214            // Note that we don't execute any pending app switches... we will
7215            // let those wait until either the timeout, or the next start
7216            // activity request.
7217            mAppSwitchesAllowedTime = 0;
7218        }
7219    }
7220
7221    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7222            String name) {
7223        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7224            return true;
7225        }
7226
7227        final int perm = checkComponentPermission(
7228                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7229                callingUid, -1, true);
7230        if (perm == PackageManager.PERMISSION_GRANTED) {
7231            return true;
7232        }
7233
7234        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7235        return false;
7236    }
7237
7238    public void setDebugApp(String packageName, boolean waitForDebugger,
7239            boolean persistent) {
7240        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7241                "setDebugApp()");
7242
7243        // Note that this is not really thread safe if there are multiple
7244        // callers into it at the same time, but that's not a situation we
7245        // care about.
7246        if (persistent) {
7247            final ContentResolver resolver = mContext.getContentResolver();
7248            Settings.System.putString(
7249                resolver, Settings.System.DEBUG_APP,
7250                packageName);
7251            Settings.System.putInt(
7252                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7253                waitForDebugger ? 1 : 0);
7254        }
7255
7256        synchronized (this) {
7257            if (!persistent) {
7258                mOrigDebugApp = mDebugApp;
7259                mOrigWaitForDebugger = mWaitForDebugger;
7260            }
7261            mDebugApp = packageName;
7262            mWaitForDebugger = waitForDebugger;
7263            mDebugTransient = !persistent;
7264            if (packageName != null) {
7265                final long origId = Binder.clearCallingIdentity();
7266                forceStopPackageLocked(packageName, -1, false, false, true, true,
7267                        UserHandle.USER_ALL);
7268                Binder.restoreCallingIdentity(origId);
7269            }
7270        }
7271    }
7272
7273    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7274        synchronized (this) {
7275            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7276            if (!isDebuggable) {
7277                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7278                    throw new SecurityException("Process not debuggable: " + app.packageName);
7279                }
7280            }
7281
7282            mOpenGlTraceApp = processName;
7283        }
7284    }
7285
7286    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7287            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7288        synchronized (this) {
7289            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7290            if (!isDebuggable) {
7291                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7292                    throw new SecurityException("Process not debuggable: " + app.packageName);
7293                }
7294            }
7295            mProfileApp = processName;
7296            mProfileFile = profileFile;
7297            if (mProfileFd != null) {
7298                try {
7299                    mProfileFd.close();
7300                } catch (IOException e) {
7301                }
7302                mProfileFd = null;
7303            }
7304            mProfileFd = profileFd;
7305            mProfileType = 0;
7306            mAutoStopProfiler = autoStopProfiler;
7307        }
7308    }
7309
7310    public void setAlwaysFinish(boolean enabled) {
7311        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7312                "setAlwaysFinish()");
7313
7314        Settings.System.putInt(
7315                mContext.getContentResolver(),
7316                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7317
7318        synchronized (this) {
7319            mAlwaysFinishActivities = enabled;
7320        }
7321    }
7322
7323    public void setActivityController(IActivityController controller) {
7324        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7325                "setActivityController()");
7326        synchronized (this) {
7327            mController = controller;
7328        }
7329    }
7330
7331    public boolean isUserAMonkey() {
7332        // For now the fact that there is a controller implies
7333        // we have a monkey.
7334        synchronized (this) {
7335            return mController != null;
7336        }
7337    }
7338
7339    public void requestBugReport() {
7340        // No permission check because this can't do anything harmful --
7341        // it will just eventually cause the user to be presented with
7342        // a UI to select where the bug report goes.
7343        SystemProperties.set("ctl.start", "bugreport");
7344    }
7345
7346    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7347        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7348                != PackageManager.PERMISSION_GRANTED) {
7349            throw new SecurityException("Requires permission "
7350                    + android.Manifest.permission.FILTER_EVENTS);
7351        }
7352
7353        ProcessRecord proc;
7354
7355        // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7356        synchronized (this) {
7357            synchronized (mPidsSelfLocked) {
7358                proc = mPidsSelfLocked.get(pid);
7359            }
7360            if (proc != null) {
7361                if (proc.debugging) {
7362                    return -1;
7363                }
7364
7365                if (mDidDexOpt) {
7366                    // Give more time since we were dexopting.
7367                    mDidDexOpt = false;
7368                    return -1;
7369                }
7370
7371                if (proc.instrumentationClass != null) {
7372                    Bundle info = new Bundle();
7373                    info.putString("shortMsg", "keyDispatchingTimedOut");
7374                    info.putString("longMsg", "Timed out while dispatching key event");
7375                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7376                    proc = null;
7377                }
7378            }
7379        }
7380
7381        if (proc != null) {
7382            appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7383            if (proc.instrumentationClass != null || proc.usingWrapper) {
7384                return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7385            }
7386        }
7387
7388        return KEY_DISPATCHING_TIMEOUT;
7389    }
7390
7391    public void registerProcessObserver(IProcessObserver observer) {
7392        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7393                "registerProcessObserver()");
7394        synchronized (this) {
7395            mProcessObservers.register(observer);
7396        }
7397    }
7398
7399    public void unregisterProcessObserver(IProcessObserver observer) {
7400        synchronized (this) {
7401            mProcessObservers.unregister(observer);
7402        }
7403    }
7404
7405    public void setImmersive(IBinder token, boolean immersive) {
7406        synchronized(this) {
7407            ActivityRecord r = mMainStack.isInStackLocked(token);
7408            if (r == null) {
7409                throw new IllegalArgumentException();
7410            }
7411            r.immersive = immersive;
7412        }
7413    }
7414
7415    public boolean isImmersive(IBinder token) {
7416        synchronized (this) {
7417            ActivityRecord r = mMainStack.isInStackLocked(token);
7418            if (r == null) {
7419                throw new IllegalArgumentException();
7420            }
7421            return r.immersive;
7422        }
7423    }
7424
7425    public boolean isTopActivityImmersive() {
7426        enforceNotIsolatedCaller("startActivity");
7427        synchronized (this) {
7428            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7429            return (r != null) ? r.immersive : false;
7430        }
7431    }
7432
7433    public final void enterSafeMode() {
7434        synchronized(this) {
7435            // It only makes sense to do this before the system is ready
7436            // and started launching other packages.
7437            if (!mSystemReady) {
7438                try {
7439                    AppGlobals.getPackageManager().enterSafeMode();
7440                } catch (RemoteException e) {
7441                }
7442            }
7443        }
7444    }
7445
7446    public final void showSafeModeOverlay() {
7447        View v = LayoutInflater.from(mContext).inflate(
7448                com.android.internal.R.layout.safe_mode, null);
7449        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7450        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7451        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7452        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7453        lp.gravity = Gravity.BOTTOM | Gravity.START;
7454        lp.format = v.getBackground().getOpacity();
7455        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7456                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7457        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7458        ((WindowManager)mContext.getSystemService(
7459                Context.WINDOW_SERVICE)).addView(v, lp);
7460    }
7461
7462    public void noteWakeupAlarm(IIntentSender sender) {
7463        if (!(sender instanceof PendingIntentRecord)) {
7464            return;
7465        }
7466        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7467        synchronized (stats) {
7468            if (mBatteryStatsService.isOnBattery()) {
7469                mBatteryStatsService.enforceCallingPermission();
7470                PendingIntentRecord rec = (PendingIntentRecord)sender;
7471                int MY_UID = Binder.getCallingUid();
7472                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7473                BatteryStatsImpl.Uid.Pkg pkg =
7474                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7475                pkg.incWakeupsLocked();
7476            }
7477        }
7478    }
7479
7480    public boolean killPids(int[] pids, String pReason, boolean secure) {
7481        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7482            throw new SecurityException("killPids only available to the system");
7483        }
7484        String reason = (pReason == null) ? "Unknown" : pReason;
7485        // XXX Note: don't acquire main activity lock here, because the window
7486        // manager calls in with its locks held.
7487
7488        boolean killed = false;
7489        synchronized (mPidsSelfLocked) {
7490            int[] types = new int[pids.length];
7491            int worstType = 0;
7492            for (int i=0; i<pids.length; i++) {
7493                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7494                if (proc != null) {
7495                    int type = proc.setAdj;
7496                    types[i] = type;
7497                    if (type > worstType) {
7498                        worstType = type;
7499                    }
7500                }
7501            }
7502
7503            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7504            // then constrain it so we will kill all hidden procs.
7505            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7506                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7507                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7508            }
7509
7510            // If this is not a secure call, don't let it kill processes that
7511            // are important.
7512            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7513                worstType = ProcessList.SERVICE_ADJ;
7514            }
7515
7516            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7517            for (int i=0; i<pids.length; i++) {
7518                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7519                if (proc == null) {
7520                    continue;
7521                }
7522                int adj = proc.setAdj;
7523                if (adj >= worstType && !proc.killedBackground) {
7524                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7525                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7526                            proc.processName, adj, reason);
7527                    killed = true;
7528                    proc.killedBackground = true;
7529                    Process.killProcessQuiet(pids[i]);
7530                }
7531            }
7532        }
7533        return killed;
7534    }
7535
7536    @Override
7537    public boolean killProcessesBelowForeground(String reason) {
7538        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7539            throw new SecurityException("killProcessesBelowForeground() only available to system");
7540        }
7541
7542        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7543    }
7544
7545    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7546        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7547            throw new SecurityException("killProcessesBelowAdj() only available to system");
7548        }
7549
7550        boolean killed = false;
7551        synchronized (mPidsSelfLocked) {
7552            final int size = mPidsSelfLocked.size();
7553            for (int i = 0; i < size; i++) {
7554                final int pid = mPidsSelfLocked.keyAt(i);
7555                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7556                if (proc == null) continue;
7557
7558                final int adj = proc.setAdj;
7559                if (adj > belowAdj && !proc.killedBackground) {
7560                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7561                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7562                            proc.pid, proc.processName, adj, reason);
7563                    killed = true;
7564                    proc.killedBackground = true;
7565                    Process.killProcessQuiet(pid);
7566                }
7567            }
7568        }
7569        return killed;
7570    }
7571
7572    public final void startRunning(String pkg, String cls, String action,
7573            String data) {
7574        synchronized(this) {
7575            if (mStartRunning) {
7576                return;
7577            }
7578            mStartRunning = true;
7579            mTopComponent = pkg != null && cls != null
7580                    ? new ComponentName(pkg, cls) : null;
7581            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7582            mTopData = data;
7583            if (!mSystemReady) {
7584                return;
7585            }
7586        }
7587
7588        systemReady(null);
7589    }
7590
7591    private void retrieveSettings() {
7592        final ContentResolver resolver = mContext.getContentResolver();
7593        String debugApp = Settings.System.getString(
7594            resolver, Settings.System.DEBUG_APP);
7595        boolean waitForDebugger = Settings.System.getInt(
7596            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7597        boolean alwaysFinishActivities = Settings.System.getInt(
7598            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7599
7600        Configuration configuration = new Configuration();
7601        Settings.System.getConfiguration(resolver, configuration);
7602
7603        synchronized (this) {
7604            mDebugApp = mOrigDebugApp = debugApp;
7605            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7606            mAlwaysFinishActivities = alwaysFinishActivities;
7607            // This happens before any activities are started, so we can
7608            // change mConfiguration in-place.
7609            updateConfigurationLocked(configuration, null, false, true);
7610            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7611        }
7612    }
7613
7614    public boolean testIsSystemReady() {
7615        // no need to synchronize(this) just to read & return the value
7616        return mSystemReady;
7617    }
7618
7619    private static File getCalledPreBootReceiversFile() {
7620        File dataDir = Environment.getDataDirectory();
7621        File systemDir = new File(dataDir, "system");
7622        File fname = new File(systemDir, "called_pre_boots.dat");
7623        return fname;
7624    }
7625
7626    static final int LAST_DONE_VERSION = 10000;
7627
7628    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7629        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7630        File file = getCalledPreBootReceiversFile();
7631        FileInputStream fis = null;
7632        try {
7633            fis = new FileInputStream(file);
7634            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7635            int fvers = dis.readInt();
7636            if (fvers == LAST_DONE_VERSION) {
7637                String vers = dis.readUTF();
7638                String codename = dis.readUTF();
7639                String build = dis.readUTF();
7640                if (android.os.Build.VERSION.RELEASE.equals(vers)
7641                        && android.os.Build.VERSION.CODENAME.equals(codename)
7642                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7643                    int num = dis.readInt();
7644                    while (num > 0) {
7645                        num--;
7646                        String pkg = dis.readUTF();
7647                        String cls = dis.readUTF();
7648                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7649                    }
7650                }
7651            }
7652        } catch (FileNotFoundException e) {
7653        } catch (IOException e) {
7654            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7655        } finally {
7656            if (fis != null) {
7657                try {
7658                    fis.close();
7659                } catch (IOException e) {
7660                }
7661            }
7662        }
7663        return lastDoneReceivers;
7664    }
7665
7666    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7667        File file = getCalledPreBootReceiversFile();
7668        FileOutputStream fos = null;
7669        DataOutputStream dos = null;
7670        try {
7671            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7672            fos = new FileOutputStream(file);
7673            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7674            dos.writeInt(LAST_DONE_VERSION);
7675            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7676            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7677            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7678            dos.writeInt(list.size());
7679            for (int i=0; i<list.size(); i++) {
7680                dos.writeUTF(list.get(i).getPackageName());
7681                dos.writeUTF(list.get(i).getClassName());
7682            }
7683        } catch (IOException e) {
7684            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7685            file.delete();
7686        } finally {
7687            FileUtils.sync(fos);
7688            if (dos != null) {
7689                try {
7690                    dos.close();
7691                } catch (IOException e) {
7692                    // TODO Auto-generated catch block
7693                    e.printStackTrace();
7694                }
7695            }
7696        }
7697    }
7698
7699    public void systemReady(final Runnable goingCallback) {
7700        synchronized(this) {
7701            if (mSystemReady) {
7702                if (goingCallback != null) goingCallback.run();
7703                return;
7704            }
7705
7706            // Check to see if there are any update receivers to run.
7707            if (!mDidUpdate) {
7708                if (mWaitingUpdate) {
7709                    return;
7710                }
7711                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7712                List<ResolveInfo> ris = null;
7713                try {
7714                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7715                            intent, null, 0, 0);
7716                } catch (RemoteException e) {
7717                }
7718                if (ris != null) {
7719                    for (int i=ris.size()-1; i>=0; i--) {
7720                        if ((ris.get(i).activityInfo.applicationInfo.flags
7721                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7722                            ris.remove(i);
7723                        }
7724                    }
7725                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7726
7727                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7728
7729                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7730                    for (int i=0; i<ris.size(); i++) {
7731                        ActivityInfo ai = ris.get(i).activityInfo;
7732                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7733                        if (lastDoneReceivers.contains(comp)) {
7734                            ris.remove(i);
7735                            i--;
7736                        }
7737                    }
7738
7739                    final int[] users = getUsersLocked();
7740                    for (int i=0; i<ris.size(); i++) {
7741                        ActivityInfo ai = ris.get(i).activityInfo;
7742                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7743                        doneReceivers.add(comp);
7744                        intent.setComponent(comp);
7745                        for (int j=0; j<users.length; j++) {
7746                            IIntentReceiver finisher = null;
7747                            if (i == ris.size()-1 && j == users.length-1) {
7748                                finisher = new IIntentReceiver.Stub() {
7749                                    public void performReceive(Intent intent, int resultCode,
7750                                            String data, Bundle extras, boolean ordered,
7751                                            boolean sticky, int sendingUser) {
7752                                        // The raw IIntentReceiver interface is called
7753                                        // with the AM lock held, so redispatch to
7754                                        // execute our code without the lock.
7755                                        mHandler.post(new Runnable() {
7756                                            public void run() {
7757                                                synchronized (ActivityManagerService.this) {
7758                                                    mDidUpdate = true;
7759                                                }
7760                                                writeLastDonePreBootReceivers(doneReceivers);
7761                                                showBootMessage(mContext.getText(
7762                                                        R.string.android_upgrading_complete),
7763                                                        false);
7764                                                systemReady(goingCallback);
7765                                            }
7766                                        });
7767                                    }
7768                                };
7769                            }
7770                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7771                                    + " for user " + users[j]);
7772                            broadcastIntentLocked(null, null, intent, null, finisher,
7773                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7774                                    users[j]);
7775                            if (finisher != null) {
7776                                mWaitingUpdate = true;
7777                            }
7778                        }
7779                    }
7780                }
7781                if (mWaitingUpdate) {
7782                    return;
7783                }
7784                mDidUpdate = true;
7785            }
7786
7787            mSystemReady = true;
7788            if (!mStartRunning) {
7789                return;
7790            }
7791        }
7792
7793        ArrayList<ProcessRecord> procsToKill = null;
7794        synchronized(mPidsSelfLocked) {
7795            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7796                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7797                if (!isAllowedWhileBooting(proc.info)){
7798                    if (procsToKill == null) {
7799                        procsToKill = new ArrayList<ProcessRecord>();
7800                    }
7801                    procsToKill.add(proc);
7802                }
7803            }
7804        }
7805
7806        synchronized(this) {
7807            if (procsToKill != null) {
7808                for (int i=procsToKill.size()-1; i>=0; i--) {
7809                    ProcessRecord proc = procsToKill.get(i);
7810                    Slog.i(TAG, "Removing system update proc: " + proc);
7811                    removeProcessLocked(proc, true, false, "system update done");
7812                }
7813            }
7814
7815            // Now that we have cleaned up any update processes, we
7816            // are ready to start launching real processes and know that
7817            // we won't trample on them any more.
7818            mProcessesReady = true;
7819        }
7820
7821        Slog.i(TAG, "System now ready");
7822        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7823            SystemClock.uptimeMillis());
7824
7825        synchronized(this) {
7826            // Make sure we have no pre-ready processes sitting around.
7827
7828            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7829                ResolveInfo ri = mContext.getPackageManager()
7830                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7831                                STOCK_PM_FLAGS);
7832                CharSequence errorMsg = null;
7833                if (ri != null) {
7834                    ActivityInfo ai = ri.activityInfo;
7835                    ApplicationInfo app = ai.applicationInfo;
7836                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7837                        mTopAction = Intent.ACTION_FACTORY_TEST;
7838                        mTopData = null;
7839                        mTopComponent = new ComponentName(app.packageName,
7840                                ai.name);
7841                    } else {
7842                        errorMsg = mContext.getResources().getText(
7843                                com.android.internal.R.string.factorytest_not_system);
7844                    }
7845                } else {
7846                    errorMsg = mContext.getResources().getText(
7847                            com.android.internal.R.string.factorytest_no_action);
7848                }
7849                if (errorMsg != null) {
7850                    mTopAction = null;
7851                    mTopData = null;
7852                    mTopComponent = null;
7853                    Message msg = Message.obtain();
7854                    msg.what = SHOW_FACTORY_ERROR_MSG;
7855                    msg.getData().putCharSequence("msg", errorMsg);
7856                    mHandler.sendMessage(msg);
7857                }
7858            }
7859        }
7860
7861        retrieveSettings();
7862
7863        if (goingCallback != null) goingCallback.run();
7864
7865        synchronized (this) {
7866            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7867                try {
7868                    List apps = AppGlobals.getPackageManager().
7869                        getPersistentApplications(STOCK_PM_FLAGS);
7870                    if (apps != null) {
7871                        int N = apps.size();
7872                        int i;
7873                        for (i=0; i<N; i++) {
7874                            ApplicationInfo info
7875                                = (ApplicationInfo)apps.get(i);
7876                            if (info != null &&
7877                                    !info.packageName.equals("android")) {
7878                                addAppLocked(info, false);
7879                            }
7880                        }
7881                    }
7882                } catch (RemoteException ex) {
7883                    // pm is in same process, this will never happen.
7884                }
7885            }
7886
7887            // Start up initial activity.
7888            mBooting = true;
7889
7890            try {
7891                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7892                    Message msg = Message.obtain();
7893                    msg.what = SHOW_UID_ERROR_MSG;
7894                    mHandler.sendMessage(msg);
7895                }
7896            } catch (RemoteException e) {
7897            }
7898
7899            long ident = Binder.clearCallingIdentity();
7900            try {
7901                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7902                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7903                        | Intent.FLAG_RECEIVER_FOREGROUND);
7904                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7905                broadcastIntentLocked(null, null, intent,
7906                        null, null, 0, null, null, null,
7907                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7908                intent = new Intent(Intent.ACTION_USER_STARTING);
7909                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7910                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7911                broadcastIntentLocked(null, null, intent,
7912                        null, new IIntentReceiver.Stub() {
7913                            @Override
7914                            public void performReceive(Intent intent, int resultCode, String data,
7915                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7916                                    throws RemoteException {
7917                            }
7918                        }, 0, null, null,
7919                        android.Manifest.permission.INTERACT_ACROSS_USERS,
7920                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
7921            } finally {
7922                Binder.restoreCallingIdentity(ident);
7923            }
7924            mMainStack.resumeTopActivityLocked(null);
7925            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7926        }
7927    }
7928
7929    private boolean makeAppCrashingLocked(ProcessRecord app,
7930            String shortMsg, String longMsg, String stackTrace) {
7931        app.crashing = true;
7932        app.crashingReport = generateProcessError(app,
7933                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7934        startAppProblemLocked(app);
7935        app.stopFreezingAllLocked();
7936        return handleAppCrashLocked(app);
7937    }
7938
7939    private void makeAppNotRespondingLocked(ProcessRecord app,
7940            String activity, String shortMsg, String longMsg) {
7941        app.notResponding = true;
7942        app.notRespondingReport = generateProcessError(app,
7943                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7944                activity, shortMsg, longMsg, null);
7945        startAppProblemLocked(app);
7946        app.stopFreezingAllLocked();
7947    }
7948
7949    /**
7950     * Generate a process error record, suitable for attachment to a ProcessRecord.
7951     *
7952     * @param app The ProcessRecord in which the error occurred.
7953     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7954     *                      ActivityManager.AppErrorStateInfo
7955     * @param activity The activity associated with the crash, if known.
7956     * @param shortMsg Short message describing the crash.
7957     * @param longMsg Long message describing the crash.
7958     * @param stackTrace Full crash stack trace, may be null.
7959     *
7960     * @return Returns a fully-formed AppErrorStateInfo record.
7961     */
7962    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7963            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7964        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7965
7966        report.condition = condition;
7967        report.processName = app.processName;
7968        report.pid = app.pid;
7969        report.uid = app.info.uid;
7970        report.tag = activity;
7971        report.shortMsg = shortMsg;
7972        report.longMsg = longMsg;
7973        report.stackTrace = stackTrace;
7974
7975        return report;
7976    }
7977
7978    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7979        synchronized (this) {
7980            app.crashing = false;
7981            app.crashingReport = null;
7982            app.notResponding = false;
7983            app.notRespondingReport = null;
7984            if (app.anrDialog == fromDialog) {
7985                app.anrDialog = null;
7986            }
7987            if (app.waitDialog == fromDialog) {
7988                app.waitDialog = null;
7989            }
7990            if (app.pid > 0 && app.pid != MY_PID) {
7991                handleAppCrashLocked(app);
7992                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7993                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
7994                        app.processName, app.setAdj, "user's request after error");
7995                Process.killProcessQuiet(app.pid);
7996            }
7997        }
7998    }
7999
8000    private boolean handleAppCrashLocked(ProcessRecord app) {
8001        if (mHeadless) {
8002            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8003            return false;
8004        }
8005        long now = SystemClock.uptimeMillis();
8006
8007        Long crashTime;
8008        if (!app.isolated) {
8009            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8010        } else {
8011            crashTime = null;
8012        }
8013        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8014            // This process loses!
8015            Slog.w(TAG, "Process " + app.info.processName
8016                    + " has crashed too many times: killing!");
8017            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8018                    app.userId, app.info.processName, app.uid);
8019            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8020                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8021                if (r.app == app) {
8022                    Slog.w(TAG, "  Force finishing activity "
8023                        + r.intent.getComponent().flattenToShortString());
8024                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8025                            null, "crashed", false);
8026                }
8027            }
8028            if (!app.persistent) {
8029                // We don't want to start this process again until the user
8030                // explicitly does so...  but for persistent process, we really
8031                // need to keep it running.  If a persistent process is actually
8032                // repeatedly crashing, then badness for everyone.
8033                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8034                        app.info.processName);
8035                if (!app.isolated) {
8036                    // XXX We don't have a way to mark isolated processes
8037                    // as bad, since they don't have a peristent identity.
8038                    mBadProcesses.put(app.info.processName, app.uid, now);
8039                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8040                }
8041                app.bad = true;
8042                app.removed = true;
8043                // Don't let services in this process be restarted and potentially
8044                // annoy the user repeatedly.  Unless it is persistent, since those
8045                // processes run critical code.
8046                removeProcessLocked(app, false, false, "crash");
8047                mMainStack.resumeTopActivityLocked(null);
8048                return false;
8049            }
8050            mMainStack.resumeTopActivityLocked(null);
8051        } else {
8052            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8053            if (r != null && r.app == app) {
8054                // If the top running activity is from this crashing
8055                // process, then terminate it to avoid getting in a loop.
8056                Slog.w(TAG, "  Force finishing activity "
8057                        + r.intent.getComponent().flattenToShortString());
8058                int index = mMainStack.indexOfActivityLocked(r);
8059                r.stack.finishActivityLocked(r, index,
8060                        Activity.RESULT_CANCELED, null, "crashed", false);
8061                // Also terminate any activities below it that aren't yet
8062                // stopped, to avoid a situation where one will get
8063                // re-start our crashing activity once it gets resumed again.
8064                index--;
8065                if (index >= 0) {
8066                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8067                    if (r.state == ActivityState.RESUMED
8068                            || r.state == ActivityState.PAUSING
8069                            || r.state == ActivityState.PAUSED) {
8070                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8071                            Slog.w(TAG, "  Force finishing activity "
8072                                    + r.intent.getComponent().flattenToShortString());
8073                            r.stack.finishActivityLocked(r, index,
8074                                    Activity.RESULT_CANCELED, null, "crashed", false);
8075                        }
8076                    }
8077                }
8078            }
8079        }
8080
8081        // Bump up the crash count of any services currently running in the proc.
8082        if (app.services.size() != 0) {
8083            // Any services running in the application need to be placed
8084            // back in the pending list.
8085            Iterator<ServiceRecord> it = app.services.iterator();
8086            while (it.hasNext()) {
8087                ServiceRecord sr = it.next();
8088                sr.crashCount++;
8089            }
8090        }
8091
8092        // If the crashing process is what we consider to be the "home process" and it has been
8093        // replaced by a third-party app, clear the package preferred activities from packages
8094        // with a home activity running in the process to prevent a repeatedly crashing app
8095        // from blocking the user to manually clear the list.
8096        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8097                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8098            Iterator it = mHomeProcess.activities.iterator();
8099            while (it.hasNext()) {
8100                ActivityRecord r = (ActivityRecord)it.next();
8101                if (r.isHomeActivity) {
8102                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8103                    try {
8104                        ActivityThread.getPackageManager()
8105                                .clearPackagePreferredActivities(r.packageName);
8106                    } catch (RemoteException c) {
8107                        // pm is in same process, this will never happen.
8108                    }
8109                }
8110            }
8111        }
8112
8113        if (!app.isolated) {
8114            // XXX Can't keep track of crash times for isolated processes,
8115            // because they don't have a perisistent identity.
8116            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8117        }
8118
8119        return true;
8120    }
8121
8122    void startAppProblemLocked(ProcessRecord app) {
8123        if (app.userId == mCurrentUserId) {
8124            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8125                    mContext, app.info.packageName, app.info.flags);
8126        } else {
8127            // If this app is not running under the current user, then we
8128            // can't give it a report button because that would require
8129            // launching the report UI under a different user.
8130            app.errorReportReceiver = null;
8131        }
8132        skipCurrentReceiverLocked(app);
8133    }
8134
8135    void skipCurrentReceiverLocked(ProcessRecord app) {
8136        for (BroadcastQueue queue : mBroadcastQueues) {
8137            queue.skipCurrentReceiverLocked(app);
8138        }
8139    }
8140
8141    /**
8142     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8143     * The application process will exit immediately after this call returns.
8144     * @param app object of the crashing app, null for the system server
8145     * @param crashInfo describing the exception
8146     */
8147    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8148        ProcessRecord r = findAppProcess(app, "Crash");
8149        final String processName = app == null ? "system_server"
8150                : (r == null ? "unknown" : r.processName);
8151
8152        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8153                UserHandle.getUserId(Binder.getCallingUid()), processName,
8154                r == null ? -1 : r.info.flags,
8155                crashInfo.exceptionClassName,
8156                crashInfo.exceptionMessage,
8157                crashInfo.throwFileName,
8158                crashInfo.throwLineNumber);
8159
8160        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8161
8162        crashApplication(r, crashInfo);
8163    }
8164
8165    public void handleApplicationStrictModeViolation(
8166            IBinder app,
8167            int violationMask,
8168            StrictMode.ViolationInfo info) {
8169        ProcessRecord r = findAppProcess(app, "StrictMode");
8170        if (r == null) {
8171            return;
8172        }
8173
8174        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8175            Integer stackFingerprint = info.hashCode();
8176            boolean logIt = true;
8177            synchronized (mAlreadyLoggedViolatedStacks) {
8178                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8179                    logIt = false;
8180                    // TODO: sub-sample into EventLog for these, with
8181                    // the info.durationMillis?  Then we'd get
8182                    // the relative pain numbers, without logging all
8183                    // the stack traces repeatedly.  We'd want to do
8184                    // likewise in the client code, which also does
8185                    // dup suppression, before the Binder call.
8186                } else {
8187                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8188                        mAlreadyLoggedViolatedStacks.clear();
8189                    }
8190                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8191                }
8192            }
8193            if (logIt) {
8194                logStrictModeViolationToDropBox(r, info);
8195            }
8196        }
8197
8198        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8199            AppErrorResult result = new AppErrorResult();
8200            synchronized (this) {
8201                final long origId = Binder.clearCallingIdentity();
8202
8203                Message msg = Message.obtain();
8204                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8205                HashMap<String, Object> data = new HashMap<String, Object>();
8206                data.put("result", result);
8207                data.put("app", r);
8208                data.put("violationMask", violationMask);
8209                data.put("info", info);
8210                msg.obj = data;
8211                mHandler.sendMessage(msg);
8212
8213                Binder.restoreCallingIdentity(origId);
8214            }
8215            int res = result.get();
8216            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8217        }
8218    }
8219
8220    // Depending on the policy in effect, there could be a bunch of
8221    // these in quick succession so we try to batch these together to
8222    // minimize disk writes, number of dropbox entries, and maximize
8223    // compression, by having more fewer, larger records.
8224    private void logStrictModeViolationToDropBox(
8225            ProcessRecord process,
8226            StrictMode.ViolationInfo info) {
8227        if (info == null) {
8228            return;
8229        }
8230        final boolean isSystemApp = process == null ||
8231                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8232                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8233        final String processName = process == null ? "unknown" : process.processName;
8234        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8235        final DropBoxManager dbox = (DropBoxManager)
8236                mContext.getSystemService(Context.DROPBOX_SERVICE);
8237
8238        // Exit early if the dropbox isn't configured to accept this report type.
8239        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8240
8241        boolean bufferWasEmpty;
8242        boolean needsFlush;
8243        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8244        synchronized (sb) {
8245            bufferWasEmpty = sb.length() == 0;
8246            appendDropBoxProcessHeaders(process, processName, sb);
8247            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8248            sb.append("System-App: ").append(isSystemApp).append("\n");
8249            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8250            if (info.violationNumThisLoop != 0) {
8251                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8252            }
8253            if (info.numAnimationsRunning != 0) {
8254                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8255            }
8256            if (info.broadcastIntentAction != null) {
8257                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8258            }
8259            if (info.durationMillis != -1) {
8260                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8261            }
8262            if (info.numInstances != -1) {
8263                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8264            }
8265            if (info.tags != null) {
8266                for (String tag : info.tags) {
8267                    sb.append("Span-Tag: ").append(tag).append("\n");
8268                }
8269            }
8270            sb.append("\n");
8271            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8272                sb.append(info.crashInfo.stackTrace);
8273            }
8274            sb.append("\n");
8275
8276            // Only buffer up to ~64k.  Various logging bits truncate
8277            // things at 128k.
8278            needsFlush = (sb.length() > 64 * 1024);
8279        }
8280
8281        // Flush immediately if the buffer's grown too large, or this
8282        // is a non-system app.  Non-system apps are isolated with a
8283        // different tag & policy and not batched.
8284        //
8285        // Batching is useful during internal testing with
8286        // StrictMode settings turned up high.  Without batching,
8287        // thousands of separate files could be created on boot.
8288        if (!isSystemApp || needsFlush) {
8289            new Thread("Error dump: " + dropboxTag) {
8290                @Override
8291                public void run() {
8292                    String report;
8293                    synchronized (sb) {
8294                        report = sb.toString();
8295                        sb.delete(0, sb.length());
8296                        sb.trimToSize();
8297                    }
8298                    if (report.length() != 0) {
8299                        dbox.addText(dropboxTag, report);
8300                    }
8301                }
8302            }.start();
8303            return;
8304        }
8305
8306        // System app batching:
8307        if (!bufferWasEmpty) {
8308            // An existing dropbox-writing thread is outstanding, so
8309            // we don't need to start it up.  The existing thread will
8310            // catch the buffer appends we just did.
8311            return;
8312        }
8313
8314        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8315        // (After this point, we shouldn't access AMS internal data structures.)
8316        new Thread("Error dump: " + dropboxTag) {
8317            @Override
8318            public void run() {
8319                // 5 second sleep to let stacks arrive and be batched together
8320                try {
8321                    Thread.sleep(5000);  // 5 seconds
8322                } catch (InterruptedException e) {}
8323
8324                String errorReport;
8325                synchronized (mStrictModeBuffer) {
8326                    errorReport = mStrictModeBuffer.toString();
8327                    if (errorReport.length() == 0) {
8328                        return;
8329                    }
8330                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8331                    mStrictModeBuffer.trimToSize();
8332                }
8333                dbox.addText(dropboxTag, errorReport);
8334            }
8335        }.start();
8336    }
8337
8338    /**
8339     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8340     * @param app object of the crashing app, null for the system server
8341     * @param tag reported by the caller
8342     * @param crashInfo describing the context of the error
8343     * @return true if the process should exit immediately (WTF is fatal)
8344     */
8345    public boolean handleApplicationWtf(IBinder app, String tag,
8346            ApplicationErrorReport.CrashInfo crashInfo) {
8347        ProcessRecord r = findAppProcess(app, "WTF");
8348        final String processName = app == null ? "system_server"
8349                : (r == null ? "unknown" : r.processName);
8350
8351        EventLog.writeEvent(EventLogTags.AM_WTF,
8352                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8353                processName,
8354                r == null ? -1 : r.info.flags,
8355                tag, crashInfo.exceptionMessage);
8356
8357        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8358
8359        if (r != null && r.pid != Process.myPid() &&
8360                Settings.Global.getInt(mContext.getContentResolver(),
8361                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8362            crashApplication(r, crashInfo);
8363            return true;
8364        } else {
8365            return false;
8366        }
8367    }
8368
8369    /**
8370     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8371     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8372     */
8373    private ProcessRecord findAppProcess(IBinder app, String reason) {
8374        if (app == null) {
8375            return null;
8376        }
8377
8378        synchronized (this) {
8379            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8380                final int NA = apps.size();
8381                for (int ia=0; ia<NA; ia++) {
8382                    ProcessRecord p = apps.valueAt(ia);
8383                    if (p.thread != null && p.thread.asBinder() == app) {
8384                        return p;
8385                    }
8386                }
8387            }
8388
8389            Slog.w(TAG, "Can't find mystery application for " + reason
8390                    + " from pid=" + Binder.getCallingPid()
8391                    + " uid=" + Binder.getCallingUid() + ": " + app);
8392            return null;
8393        }
8394    }
8395
8396    /**
8397     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8398     * to append various headers to the dropbox log text.
8399     */
8400    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8401            StringBuilder sb) {
8402        // Watchdog thread ends up invoking this function (with
8403        // a null ProcessRecord) to add the stack file to dropbox.
8404        // Do not acquire a lock on this (am) in such cases, as it
8405        // could cause a potential deadlock, if and when watchdog
8406        // is invoked due to unavailability of lock on am and it
8407        // would prevent watchdog from killing system_server.
8408        if (process == null) {
8409            sb.append("Process: ").append(processName).append("\n");
8410            return;
8411        }
8412        // Note: ProcessRecord 'process' is guarded by the service
8413        // instance.  (notably process.pkgList, which could otherwise change
8414        // concurrently during execution of this method)
8415        synchronized (this) {
8416            sb.append("Process: ").append(processName).append("\n");
8417            int flags = process.info.flags;
8418            IPackageManager pm = AppGlobals.getPackageManager();
8419            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8420            for (String pkg : process.pkgList) {
8421                sb.append("Package: ").append(pkg);
8422                try {
8423                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8424                    if (pi != null) {
8425                        sb.append(" v").append(pi.versionCode);
8426                        if (pi.versionName != null) {
8427                            sb.append(" (").append(pi.versionName).append(")");
8428                        }
8429                    }
8430                } catch (RemoteException e) {
8431                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8432                }
8433                sb.append("\n");
8434            }
8435        }
8436    }
8437
8438    private static String processClass(ProcessRecord process) {
8439        if (process == null || process.pid == MY_PID) {
8440            return "system_server";
8441        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8442            return "system_app";
8443        } else {
8444            return "data_app";
8445        }
8446    }
8447
8448    /**
8449     * Write a description of an error (crash, WTF, ANR) to the drop box.
8450     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8451     * @param process which caused the error, null means the system server
8452     * @param activity which triggered the error, null if unknown
8453     * @param parent activity related to the error, null if unknown
8454     * @param subject line related to the error, null if absent
8455     * @param report in long form describing the error, null if absent
8456     * @param logFile to include in the report, null if none
8457     * @param crashInfo giving an application stack trace, null if absent
8458     */
8459    public void addErrorToDropBox(String eventType,
8460            ProcessRecord process, String processName, ActivityRecord activity,
8461            ActivityRecord parent, String subject,
8462            final String report, final File logFile,
8463            final ApplicationErrorReport.CrashInfo crashInfo) {
8464        // NOTE -- this must never acquire the ActivityManagerService lock,
8465        // otherwise the watchdog may be prevented from resetting the system.
8466
8467        final String dropboxTag = processClass(process) + "_" + eventType;
8468        final DropBoxManager dbox = (DropBoxManager)
8469                mContext.getSystemService(Context.DROPBOX_SERVICE);
8470
8471        // Exit early if the dropbox isn't configured to accept this report type.
8472        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8473
8474        final StringBuilder sb = new StringBuilder(1024);
8475        appendDropBoxProcessHeaders(process, processName, sb);
8476        if (activity != null) {
8477            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8478        }
8479        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8480            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8481        }
8482        if (parent != null && parent != activity) {
8483            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8484        }
8485        if (subject != null) {
8486            sb.append("Subject: ").append(subject).append("\n");
8487        }
8488        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8489        if (Debug.isDebuggerConnected()) {
8490            sb.append("Debugger: Connected\n");
8491        }
8492        sb.append("\n");
8493
8494        // Do the rest in a worker thread to avoid blocking the caller on I/O
8495        // (After this point, we shouldn't access AMS internal data structures.)
8496        Thread worker = new Thread("Error dump: " + dropboxTag) {
8497            @Override
8498            public void run() {
8499                if (report != null) {
8500                    sb.append(report);
8501                }
8502                if (logFile != null) {
8503                    try {
8504                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8505                    } catch (IOException e) {
8506                        Slog.e(TAG, "Error reading " + logFile, e);
8507                    }
8508                }
8509                if (crashInfo != null && crashInfo.stackTrace != null) {
8510                    sb.append(crashInfo.stackTrace);
8511                }
8512
8513                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8514                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8515                if (lines > 0) {
8516                    sb.append("\n");
8517
8518                    // Merge several logcat streams, and take the last N lines
8519                    InputStreamReader input = null;
8520                    try {
8521                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8522                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8523                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8524
8525                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8526                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8527                        input = new InputStreamReader(logcat.getInputStream());
8528
8529                        int num;
8530                        char[] buf = new char[8192];
8531                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8532                    } catch (IOException e) {
8533                        Slog.e(TAG, "Error running logcat", e);
8534                    } finally {
8535                        if (input != null) try { input.close(); } catch (IOException e) {}
8536                    }
8537                }
8538
8539                dbox.addText(dropboxTag, sb.toString());
8540            }
8541        };
8542
8543        if (process == null) {
8544            // If process is null, we are being called from some internal code
8545            // and may be about to die -- run this synchronously.
8546            worker.run();
8547        } else {
8548            worker.start();
8549        }
8550    }
8551
8552    /**
8553     * Bring up the "unexpected error" dialog box for a crashing app.
8554     * Deal with edge cases (intercepts from instrumented applications,
8555     * ActivityController, error intent receivers, that sort of thing).
8556     * @param r the application crashing
8557     * @param crashInfo describing the failure
8558     */
8559    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8560        long timeMillis = System.currentTimeMillis();
8561        String shortMsg = crashInfo.exceptionClassName;
8562        String longMsg = crashInfo.exceptionMessage;
8563        String stackTrace = crashInfo.stackTrace;
8564        if (shortMsg != null && longMsg != null) {
8565            longMsg = shortMsg + ": " + longMsg;
8566        } else if (shortMsg != null) {
8567            longMsg = shortMsg;
8568        }
8569
8570        AppErrorResult result = new AppErrorResult();
8571        synchronized (this) {
8572            if (mController != null) {
8573                try {
8574                    String name = r != null ? r.processName : null;
8575                    int pid = r != null ? r.pid : Binder.getCallingPid();
8576                    if (!mController.appCrashed(name, pid,
8577                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8578                        Slog.w(TAG, "Force-killing crashed app " + name
8579                                + " at watcher's request");
8580                        Process.killProcess(pid);
8581                        return;
8582                    }
8583                } catch (RemoteException e) {
8584                    mController = null;
8585                }
8586            }
8587
8588            final long origId = Binder.clearCallingIdentity();
8589
8590            // If this process is running instrumentation, finish it.
8591            if (r != null && r.instrumentationClass != null) {
8592                Slog.w(TAG, "Error in app " + r.processName
8593                      + " running instrumentation " + r.instrumentationClass + ":");
8594                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8595                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8596                Bundle info = new Bundle();
8597                info.putString("shortMsg", shortMsg);
8598                info.putString("longMsg", longMsg);
8599                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8600                Binder.restoreCallingIdentity(origId);
8601                return;
8602            }
8603
8604            // If we can't identify the process or it's already exceeded its crash quota,
8605            // quit right away without showing a crash dialog.
8606            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8607                Binder.restoreCallingIdentity(origId);
8608                return;
8609            }
8610
8611            Message msg = Message.obtain();
8612            msg.what = SHOW_ERROR_MSG;
8613            HashMap data = new HashMap();
8614            data.put("result", result);
8615            data.put("app", r);
8616            msg.obj = data;
8617            mHandler.sendMessage(msg);
8618
8619            Binder.restoreCallingIdentity(origId);
8620        }
8621
8622        int res = result.get();
8623
8624        Intent appErrorIntent = null;
8625        synchronized (this) {
8626            if (r != null && !r.isolated) {
8627                // XXX Can't keep track of crash time for isolated processes,
8628                // since they don't have a persistent identity.
8629                mProcessCrashTimes.put(r.info.processName, r.uid,
8630                        SystemClock.uptimeMillis());
8631            }
8632            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8633                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8634            }
8635        }
8636
8637        if (appErrorIntent != null) {
8638            try {
8639                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8640            } catch (ActivityNotFoundException e) {
8641                Slog.w(TAG, "bug report receiver dissappeared", e);
8642            }
8643        }
8644    }
8645
8646    Intent createAppErrorIntentLocked(ProcessRecord r,
8647            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8648        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8649        if (report == null) {
8650            return null;
8651        }
8652        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8653        result.setComponent(r.errorReportReceiver);
8654        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8655        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8656        return result;
8657    }
8658
8659    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8660            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8661        if (r.errorReportReceiver == null) {
8662            return null;
8663        }
8664
8665        if (!r.crashing && !r.notResponding) {
8666            return null;
8667        }
8668
8669        ApplicationErrorReport report = new ApplicationErrorReport();
8670        report.packageName = r.info.packageName;
8671        report.installerPackageName = r.errorReportReceiver.getPackageName();
8672        report.processName = r.processName;
8673        report.time = timeMillis;
8674        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8675
8676        if (r.crashing) {
8677            report.type = ApplicationErrorReport.TYPE_CRASH;
8678            report.crashInfo = crashInfo;
8679        } else if (r.notResponding) {
8680            report.type = ApplicationErrorReport.TYPE_ANR;
8681            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8682
8683            report.anrInfo.activity = r.notRespondingReport.tag;
8684            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8685            report.anrInfo.info = r.notRespondingReport.longMsg;
8686        }
8687
8688        return report;
8689    }
8690
8691    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8692        enforceNotIsolatedCaller("getProcessesInErrorState");
8693        // assume our apps are happy - lazy create the list
8694        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8695
8696        final boolean allUsers = ActivityManager.checkUidPermission(
8697                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8698                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8699        int userId = UserHandle.getUserId(Binder.getCallingUid());
8700
8701        synchronized (this) {
8702
8703            // iterate across all processes
8704            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8705                ProcessRecord app = mLruProcesses.get(i);
8706                if (!allUsers && app.userId != userId) {
8707                    continue;
8708                }
8709                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8710                    // This one's in trouble, so we'll generate a report for it
8711                    // crashes are higher priority (in case there's a crash *and* an anr)
8712                    ActivityManager.ProcessErrorStateInfo report = null;
8713                    if (app.crashing) {
8714                        report = app.crashingReport;
8715                    } else if (app.notResponding) {
8716                        report = app.notRespondingReport;
8717                    }
8718
8719                    if (report != null) {
8720                        if (errList == null) {
8721                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8722                        }
8723                        errList.add(report);
8724                    } else {
8725                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8726                                " crashing = " + app.crashing +
8727                                " notResponding = " + app.notResponding);
8728                    }
8729                }
8730            }
8731        }
8732
8733        return errList;
8734    }
8735
8736    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8737        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8738            if (currApp != null) {
8739                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8740            }
8741            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8742        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8743            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8744        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8745            if (currApp != null) {
8746                currApp.lru = 0;
8747            }
8748            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8749        } else if (adj >= ProcessList.SERVICE_ADJ) {
8750            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8751        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8752            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8753        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8754            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8755        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8756            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8757        } else {
8758            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8759        }
8760    }
8761
8762    private void fillInProcMemInfo(ProcessRecord app,
8763            ActivityManager.RunningAppProcessInfo outInfo) {
8764        outInfo.pid = app.pid;
8765        outInfo.uid = app.info.uid;
8766        if (mHeavyWeightProcess == app) {
8767            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8768        }
8769        if (app.persistent) {
8770            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8771        }
8772        if (app.hasActivities) {
8773            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8774        }
8775        outInfo.lastTrimLevel = app.trimMemoryLevel;
8776        int adj = app.curAdj;
8777        outInfo.importance = oomAdjToImportance(adj, outInfo);
8778        outInfo.importanceReasonCode = app.adjTypeCode;
8779    }
8780
8781    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8782        enforceNotIsolatedCaller("getRunningAppProcesses");
8783        // Lazy instantiation of list
8784        List<ActivityManager.RunningAppProcessInfo> runList = null;
8785        final boolean allUsers = ActivityManager.checkUidPermission(
8786                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8787                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8788        int userId = UserHandle.getUserId(Binder.getCallingUid());
8789        synchronized (this) {
8790            // Iterate across all processes
8791            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8792                ProcessRecord app = mLruProcesses.get(i);
8793                if (!allUsers && app.userId != userId) {
8794                    continue;
8795                }
8796                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8797                    // Generate process state info for running application
8798                    ActivityManager.RunningAppProcessInfo currApp =
8799                        new ActivityManager.RunningAppProcessInfo(app.processName,
8800                                app.pid, app.getPackageList());
8801                    fillInProcMemInfo(app, currApp);
8802                    if (app.adjSource instanceof ProcessRecord) {
8803                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8804                        currApp.importanceReasonImportance = oomAdjToImportance(
8805                                app.adjSourceOom, null);
8806                    } else if (app.adjSource instanceof ActivityRecord) {
8807                        ActivityRecord r = (ActivityRecord)app.adjSource;
8808                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8809                    }
8810                    if (app.adjTarget instanceof ComponentName) {
8811                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8812                    }
8813                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8814                    //        + " lru=" + currApp.lru);
8815                    if (runList == null) {
8816                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8817                    }
8818                    runList.add(currApp);
8819                }
8820            }
8821        }
8822        return runList;
8823    }
8824
8825    public List<ApplicationInfo> getRunningExternalApplications() {
8826        enforceNotIsolatedCaller("getRunningExternalApplications");
8827        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8828        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8829        if (runningApps != null && runningApps.size() > 0) {
8830            Set<String> extList = new HashSet<String>();
8831            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8832                if (app.pkgList != null) {
8833                    for (String pkg : app.pkgList) {
8834                        extList.add(pkg);
8835                    }
8836                }
8837            }
8838            IPackageManager pm = AppGlobals.getPackageManager();
8839            for (String pkg : extList) {
8840                try {
8841                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8842                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8843                        retList.add(info);
8844                    }
8845                } catch (RemoteException e) {
8846                }
8847            }
8848        }
8849        return retList;
8850    }
8851
8852    @Override
8853    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8854        enforceNotIsolatedCaller("getMyMemoryState");
8855        synchronized (this) {
8856            ProcessRecord proc;
8857            synchronized (mPidsSelfLocked) {
8858                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8859            }
8860            fillInProcMemInfo(proc, outInfo);
8861        }
8862    }
8863
8864    @Override
8865    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8866        if (checkCallingPermission(android.Manifest.permission.DUMP)
8867                != PackageManager.PERMISSION_GRANTED) {
8868            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8869                    + Binder.getCallingPid()
8870                    + ", uid=" + Binder.getCallingUid()
8871                    + " without permission "
8872                    + android.Manifest.permission.DUMP);
8873            return;
8874        }
8875
8876        boolean dumpAll = false;
8877        boolean dumpClient = false;
8878        String dumpPackage = null;
8879
8880        int opti = 0;
8881        while (opti < args.length) {
8882            String opt = args[opti];
8883            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8884                break;
8885            }
8886            opti++;
8887            if ("-a".equals(opt)) {
8888                dumpAll = true;
8889            } else if ("-c".equals(opt)) {
8890                dumpClient = true;
8891            } else if ("-h".equals(opt)) {
8892                pw.println("Activity manager dump options:");
8893                pw.println("  [-a] [-c] [-h] [cmd] ...");
8894                pw.println("  cmd may be one of:");
8895                pw.println("    a[ctivities]: activity stack state");
8896                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
8897                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8898                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8899                pw.println("    o[om]: out of memory management");
8900                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8901                pw.println("    provider [COMP_SPEC]: provider client-side state");
8902                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8903                pw.println("    service [COMP_SPEC]: service client-side state");
8904                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8905                pw.println("    all: dump all activities");
8906                pw.println("    top: dump the top activity");
8907                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8908                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8909                pw.println("    a partial substring in a component name, a");
8910                pw.println("    hex object identifier.");
8911                pw.println("  -a: include all available server state.");
8912                pw.println("  -c: include client state.");
8913                return;
8914            } else {
8915                pw.println("Unknown argument: " + opt + "; use -h for help");
8916            }
8917        }
8918
8919        long origId = Binder.clearCallingIdentity();
8920        boolean more = false;
8921        // Is the caller requesting to dump a particular piece of data?
8922        if (opti < args.length) {
8923            String cmd = args[opti];
8924            opti++;
8925            if ("activities".equals(cmd) || "a".equals(cmd)) {
8926                synchronized (this) {
8927                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8928                }
8929            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8930                String[] newArgs;
8931                String name;
8932                if (opti >= args.length) {
8933                    name = null;
8934                    newArgs = EMPTY_STRING_ARRAY;
8935                } else {
8936                    name = args[opti];
8937                    opti++;
8938                    newArgs = new String[args.length - opti];
8939                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8940                            args.length - opti);
8941                }
8942                synchronized (this) {
8943                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8944                }
8945            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8946                String[] newArgs;
8947                String name;
8948                if (opti >= args.length) {
8949                    name = null;
8950                    newArgs = EMPTY_STRING_ARRAY;
8951                } else {
8952                    name = args[opti];
8953                    opti++;
8954                    newArgs = new String[args.length - opti];
8955                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8956                            args.length - opti);
8957                }
8958                synchronized (this) {
8959                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8960                }
8961            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8962                String[] newArgs;
8963                String name;
8964                if (opti >= args.length) {
8965                    name = null;
8966                    newArgs = EMPTY_STRING_ARRAY;
8967                } else {
8968                    name = args[opti];
8969                    opti++;
8970                    newArgs = new String[args.length - opti];
8971                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8972                            args.length - opti);
8973                }
8974                synchronized (this) {
8975                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8976                }
8977            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8978                synchronized (this) {
8979                    dumpOomLocked(fd, pw, args, opti, true);
8980                }
8981            } else if ("provider".equals(cmd)) {
8982                String[] newArgs;
8983                String name;
8984                if (opti >= args.length) {
8985                    name = null;
8986                    newArgs = EMPTY_STRING_ARRAY;
8987                } else {
8988                    name = args[opti];
8989                    opti++;
8990                    newArgs = new String[args.length - opti];
8991                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8992                }
8993                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8994                    pw.println("No providers match: " + name);
8995                    pw.println("Use -h for help.");
8996                }
8997            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8998                synchronized (this) {
8999                    dumpProvidersLocked(fd, pw, args, opti, true, null);
9000                }
9001            } else if ("service".equals(cmd)) {
9002                String[] newArgs;
9003                String name;
9004                if (opti >= args.length) {
9005                    name = null;
9006                    newArgs = EMPTY_STRING_ARRAY;
9007                } else {
9008                    name = args[opti];
9009                    opti++;
9010                    newArgs = new String[args.length - opti];
9011                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9012                            args.length - opti);
9013                }
9014                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9015                    pw.println("No services match: " + name);
9016                    pw.println("Use -h for help.");
9017                }
9018            } else if ("package".equals(cmd)) {
9019                String[] newArgs;
9020                if (opti >= args.length) {
9021                    pw.println("package: no package name specified");
9022                    pw.println("Use -h for help.");
9023                } else {
9024                    dumpPackage = args[opti];
9025                    opti++;
9026                    newArgs = new String[args.length - opti];
9027                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9028                            args.length - opti);
9029                    args = newArgs;
9030                    opti = 0;
9031                    more = true;
9032                }
9033            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9034                synchronized (this) {
9035                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9036                }
9037            } else {
9038                // Dumping a single activity?
9039                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9040                    pw.println("Bad activity command, or no activities match: " + cmd);
9041                    pw.println("Use -h for help.");
9042                }
9043            }
9044            if (!more) {
9045                Binder.restoreCallingIdentity(origId);
9046                return;
9047            }
9048        }
9049
9050        // No piece of data specified, dump everything.
9051        synchronized (this) {
9052            boolean needSep;
9053            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9054            if (needSep) {
9055                pw.println(" ");
9056            }
9057            if (dumpAll) {
9058                pw.println("-------------------------------------------------------------------------------");
9059            }
9060            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9061            if (needSep) {
9062                pw.println(" ");
9063            }
9064            if (dumpAll) {
9065                pw.println("-------------------------------------------------------------------------------");
9066            }
9067            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9068            if (needSep) {
9069                pw.println(" ");
9070            }
9071            if (dumpAll) {
9072                pw.println("-------------------------------------------------------------------------------");
9073            }
9074            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9075            if (needSep) {
9076                pw.println(" ");
9077            }
9078            if (dumpAll) {
9079                pw.println("-------------------------------------------------------------------------------");
9080            }
9081            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9082            if (needSep) {
9083                pw.println(" ");
9084            }
9085            if (dumpAll) {
9086                pw.println("-------------------------------------------------------------------------------");
9087            }
9088            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9089        }
9090        Binder.restoreCallingIdentity(origId);
9091    }
9092
9093    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9094            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9095        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9096        pw.println("  Main stack:");
9097        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9098                dumpPackage);
9099        pw.println(" ");
9100        pw.println("  Running activities (most recent first):");
9101        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9102                dumpPackage);
9103        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9104            pw.println(" ");
9105            pw.println("  Activities waiting for another to become visible:");
9106            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9107                    !dumpAll, false, dumpPackage);
9108        }
9109        if (mMainStack.mStoppingActivities.size() > 0) {
9110            pw.println(" ");
9111            pw.println("  Activities waiting to stop:");
9112            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9113                    !dumpAll, false, dumpPackage);
9114        }
9115        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9116            pw.println(" ");
9117            pw.println("  Activities waiting to sleep:");
9118            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9119                    !dumpAll, false, dumpPackage);
9120        }
9121        if (mMainStack.mFinishingActivities.size() > 0) {
9122            pw.println(" ");
9123            pw.println("  Activities waiting to finish:");
9124            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9125                    !dumpAll, false, dumpPackage);
9126        }
9127
9128        pw.println(" ");
9129        if (mMainStack.mPausingActivity != null) {
9130            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9131        }
9132        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9133        pw.println("  mFocusedActivity: " + mFocusedActivity);
9134        if (dumpAll) {
9135            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9136            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9137            pw.println("  mDismissKeyguardOnNextActivity: "
9138                    + mMainStack.mDismissKeyguardOnNextActivity);
9139        }
9140
9141        if (mRecentTasks.size() > 0) {
9142            pw.println();
9143            pw.println("  Recent tasks:");
9144
9145            final int N = mRecentTasks.size();
9146            for (int i=0; i<N; i++) {
9147                TaskRecord tr = mRecentTasks.get(i);
9148                if (dumpPackage != null) {
9149                    if (tr.realActivity == null ||
9150                            !dumpPackage.equals(tr.realActivity)) {
9151                        continue;
9152                    }
9153                }
9154                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9155                        pw.println(tr);
9156                if (dumpAll) {
9157                    mRecentTasks.get(i).dump(pw, "    ");
9158                }
9159            }
9160        }
9161
9162        if (dumpAll) {
9163            pw.println(" ");
9164            pw.println("  mCurTask: " + mCurTask);
9165        }
9166
9167        return true;
9168    }
9169
9170    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9171            int opti, boolean dumpAll, String dumpPackage) {
9172        boolean needSep = false;
9173        int numPers = 0;
9174
9175        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9176
9177        if (dumpAll) {
9178            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9179                final int NA = procs.size();
9180                for (int ia=0; ia<NA; ia++) {
9181                    ProcessRecord r = procs.valueAt(ia);
9182                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9183                        continue;
9184                    }
9185                    if (!needSep) {
9186                        pw.println("  All known processes:");
9187                        needSep = true;
9188                    }
9189                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9190                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9191                        pw.print(" "); pw.println(r);
9192                    r.dump(pw, "    ");
9193                    if (r.persistent) {
9194                        numPers++;
9195                    }
9196                }
9197            }
9198        }
9199
9200        if (mIsolatedProcesses.size() > 0) {
9201            if (needSep) pw.println(" ");
9202            needSep = true;
9203            pw.println("  Isolated process list (sorted by uid):");
9204            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9205                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9206                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9207                    continue;
9208                }
9209                pw.println(String.format("%sIsolated #%2d: %s",
9210                        "    ", i, r.toString()));
9211            }
9212        }
9213
9214        if (mLruProcesses.size() > 0) {
9215            if (needSep) pw.println(" ");
9216            needSep = true;
9217            pw.println("  Process LRU list (sorted by oom_adj):");
9218            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9219                    "Proc", "PERS", false, dumpPackage);
9220            needSep = true;
9221        }
9222
9223        if (dumpAll) {
9224            synchronized (mPidsSelfLocked) {
9225                boolean printed = false;
9226                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9227                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9228                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9229                        continue;
9230                    }
9231                    if (!printed) {
9232                        if (needSep) pw.println(" ");
9233                        needSep = true;
9234                        pw.println("  PID mappings:");
9235                        printed = true;
9236                    }
9237                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9238                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9239                }
9240            }
9241        }
9242
9243        if (mForegroundProcesses.size() > 0) {
9244            synchronized (mPidsSelfLocked) {
9245                boolean printed = false;
9246                for (int i=0; i<mForegroundProcesses.size(); i++) {
9247                    ProcessRecord r = mPidsSelfLocked.get(
9248                            mForegroundProcesses.valueAt(i).pid);
9249                    if (dumpPackage != null && (r == null
9250                            || !dumpPackage.equals(r.info.packageName))) {
9251                        continue;
9252                    }
9253                    if (!printed) {
9254                        if (needSep) pw.println(" ");
9255                        needSep = true;
9256                        pw.println("  Foreground Processes:");
9257                        printed = true;
9258                    }
9259                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9260                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9261                }
9262            }
9263        }
9264
9265        if (mPersistentStartingProcesses.size() > 0) {
9266            if (needSep) pw.println(" ");
9267            needSep = true;
9268            pw.println("  Persisent processes that are starting:");
9269            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9270                    "Starting Norm", "Restarting PERS", dumpPackage);
9271        }
9272
9273        if (mRemovedProcesses.size() > 0) {
9274            if (needSep) pw.println(" ");
9275            needSep = true;
9276            pw.println("  Processes that are being removed:");
9277            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9278                    "Removed Norm", "Removed PERS", dumpPackage);
9279        }
9280
9281        if (mProcessesOnHold.size() > 0) {
9282            if (needSep) pw.println(" ");
9283            needSep = true;
9284            pw.println("  Processes that are on old until the system is ready:");
9285            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9286                    "OnHold Norm", "OnHold PERS", dumpPackage);
9287        }
9288
9289        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9290
9291        if (mProcessCrashTimes.getMap().size() > 0) {
9292            boolean printed = false;
9293            long now = SystemClock.uptimeMillis();
9294            for (Map.Entry<String, SparseArray<Long>> procs
9295                    : mProcessCrashTimes.getMap().entrySet()) {
9296                String pname = procs.getKey();
9297                SparseArray<Long> uids = procs.getValue();
9298                final int N = uids.size();
9299                for (int i=0; i<N; i++) {
9300                    int puid = uids.keyAt(i);
9301                    ProcessRecord r = mProcessNames.get(pname, puid);
9302                    if (dumpPackage != null && (r == null
9303                            || !dumpPackage.equals(r.info.packageName))) {
9304                        continue;
9305                    }
9306                    if (!printed) {
9307                        if (needSep) pw.println(" ");
9308                        needSep = true;
9309                        pw.println("  Time since processes crashed:");
9310                        printed = true;
9311                    }
9312                    pw.print("    Process "); pw.print(pname);
9313                            pw.print(" uid "); pw.print(puid);
9314                            pw.print(": last crashed ");
9315                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9316                            pw.println(" ago");
9317                }
9318            }
9319        }
9320
9321        if (mBadProcesses.getMap().size() > 0) {
9322            boolean printed = false;
9323            for (Map.Entry<String, SparseArray<Long>> procs
9324                    : mBadProcesses.getMap().entrySet()) {
9325                String pname = procs.getKey();
9326                SparseArray<Long> uids = procs.getValue();
9327                final int N = uids.size();
9328                for (int i=0; i<N; i++) {
9329                    int puid = uids.keyAt(i);
9330                    ProcessRecord r = mProcessNames.get(pname, puid);
9331                    if (dumpPackage != null && (r == null
9332                            || !dumpPackage.equals(r.info.packageName))) {
9333                        continue;
9334                    }
9335                    if (!printed) {
9336                        if (needSep) pw.println(" ");
9337                        needSep = true;
9338                        pw.println("  Bad processes:");
9339                    }
9340                    pw.print("    Bad process "); pw.print(pname);
9341                            pw.print(" uid "); pw.print(puid);
9342                            pw.print(": crashed at time ");
9343                            pw.println(uids.valueAt(i));
9344                }
9345            }
9346        }
9347
9348        pw.println();
9349        pw.println("  mStartedUsers:");
9350        for (int i=0; i<mStartedUsers.size(); i++) {
9351            UserStartedState uss = mStartedUsers.valueAt(i);
9352            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9353                    pw.print(": "); uss.dump("", pw);
9354        }
9355        pw.print("  mStartedUserArray: [");
9356        for (int i=0; i<mStartedUserArray.length; i++) {
9357            if (i > 0) pw.print(", ");
9358            pw.print(mStartedUserArray[i]);
9359        }
9360        pw.println("]");
9361        pw.print("  mUserLru: [");
9362        for (int i=0; i<mUserLru.size(); i++) {
9363            if (i > 0) pw.print(", ");
9364            pw.print(mUserLru.get(i));
9365        }
9366        pw.println("]");
9367        if (dumpAll) {
9368            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9369        }
9370        pw.println("  mHomeProcess: " + mHomeProcess);
9371        pw.println("  mPreviousProcess: " + mPreviousProcess);
9372        if (dumpAll) {
9373            StringBuilder sb = new StringBuilder(128);
9374            sb.append("  mPreviousProcessVisibleTime: ");
9375            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9376            pw.println(sb);
9377        }
9378        if (mHeavyWeightProcess != null) {
9379            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9380        }
9381        pw.println("  mConfiguration: " + mConfiguration);
9382        if (dumpAll) {
9383            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9384            if (mCompatModePackages.getPackages().size() > 0) {
9385                boolean printed = false;
9386                for (Map.Entry<String, Integer> entry
9387                        : mCompatModePackages.getPackages().entrySet()) {
9388                    String pkg = entry.getKey();
9389                    int mode = entry.getValue();
9390                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9391                        continue;
9392                    }
9393                    if (!printed) {
9394                        pw.println("  mScreenCompatPackages:");
9395                        printed = true;
9396                    }
9397                    pw.print("    "); pw.print(pkg); pw.print(": ");
9398                            pw.print(mode); pw.println();
9399                }
9400            }
9401        }
9402        if (mSleeping || mWentToSleep || mLockScreenShown) {
9403            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9404                    + " mLockScreenShown " + mLockScreenShown);
9405        }
9406        if (mShuttingDown) {
9407            pw.println("  mShuttingDown=" + mShuttingDown);
9408        }
9409        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9410                || mOrigWaitForDebugger) {
9411            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9412                    + " mDebugTransient=" + mDebugTransient
9413                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9414        }
9415        if (mOpenGlTraceApp != null) {
9416            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9417        }
9418        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9419                || mProfileFd != null) {
9420            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9421            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9422            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9423                    + mAutoStopProfiler);
9424        }
9425        if (mAlwaysFinishActivities || mController != null) {
9426            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9427                    + " mController=" + mController);
9428        }
9429        if (dumpAll) {
9430            pw.println("  Total persistent processes: " + numPers);
9431            pw.println("  mStartRunning=" + mStartRunning
9432                    + " mProcessesReady=" + mProcessesReady
9433                    + " mSystemReady=" + mSystemReady);
9434            pw.println("  mBooting=" + mBooting
9435                    + " mBooted=" + mBooted
9436                    + " mFactoryTest=" + mFactoryTest);
9437            pw.print("  mLastPowerCheckRealtime=");
9438                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9439                    pw.println("");
9440            pw.print("  mLastPowerCheckUptime=");
9441                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9442                    pw.println("");
9443            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9444            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9445            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9446            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9447                    + " mNumHiddenProcs=" + mNumHiddenProcs
9448                    + " mNumServiceProcs=" + mNumServiceProcs
9449                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9450        }
9451
9452        return true;
9453    }
9454
9455    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9456            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9457        if (mProcessesToGc.size() > 0) {
9458            boolean printed = false;
9459            long now = SystemClock.uptimeMillis();
9460            for (int i=0; i<mProcessesToGc.size(); i++) {
9461                ProcessRecord proc = mProcessesToGc.get(i);
9462                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9463                    continue;
9464                }
9465                if (!printed) {
9466                    if (needSep) pw.println(" ");
9467                    needSep = true;
9468                    pw.println("  Processes that are waiting to GC:");
9469                    printed = true;
9470                }
9471                pw.print("    Process "); pw.println(proc);
9472                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9473                        pw.print(", last gced=");
9474                        pw.print(now-proc.lastRequestedGc);
9475                        pw.print(" ms ago, last lowMem=");
9476                        pw.print(now-proc.lastLowMemory);
9477                        pw.println(" ms ago");
9478
9479            }
9480        }
9481        return needSep;
9482    }
9483
9484    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9485            int opti, boolean dumpAll) {
9486        boolean needSep = false;
9487
9488        if (mLruProcesses.size() > 0) {
9489            if (needSep) pw.println(" ");
9490            needSep = true;
9491            pw.println("  OOM levels:");
9492            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9493            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9494            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9495            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9496            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9497            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9498            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9499            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9500            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9501            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9502            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9503            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9504            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9505
9506            if (needSep) pw.println(" ");
9507            needSep = true;
9508            pw.println("  Process OOM control:");
9509            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9510                    "Proc", "PERS", true, null);
9511            needSep = true;
9512        }
9513
9514        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9515
9516        pw.println();
9517        pw.println("  mHomeProcess: " + mHomeProcess);
9518        pw.println("  mPreviousProcess: " + mPreviousProcess);
9519        if (mHeavyWeightProcess != null) {
9520            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9521        }
9522
9523        return true;
9524    }
9525
9526    /**
9527     * There are three ways to call this:
9528     *  - no provider specified: dump all the providers
9529     *  - a flattened component name that matched an existing provider was specified as the
9530     *    first arg: dump that one provider
9531     *  - the first arg isn't the flattened component name of an existing provider:
9532     *    dump all providers whose component contains the first arg as a substring
9533     */
9534    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9535            int opti, boolean dumpAll) {
9536        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9537    }
9538
9539    static class ItemMatcher {
9540        ArrayList<ComponentName> components;
9541        ArrayList<String> strings;
9542        ArrayList<Integer> objects;
9543        boolean all;
9544
9545        ItemMatcher() {
9546            all = true;
9547        }
9548
9549        void build(String name) {
9550            ComponentName componentName = ComponentName.unflattenFromString(name);
9551            if (componentName != null) {
9552                if (components == null) {
9553                    components = new ArrayList<ComponentName>();
9554                }
9555                components.add(componentName);
9556                all = false;
9557            } else {
9558                int objectId = 0;
9559                // Not a '/' separated full component name; maybe an object ID?
9560                try {
9561                    objectId = Integer.parseInt(name, 16);
9562                    if (objects == null) {
9563                        objects = new ArrayList<Integer>();
9564                    }
9565                    objects.add(objectId);
9566                    all = false;
9567                } catch (RuntimeException e) {
9568                    // Not an integer; just do string match.
9569                    if (strings == null) {
9570                        strings = new ArrayList<String>();
9571                    }
9572                    strings.add(name);
9573                    all = false;
9574                }
9575            }
9576        }
9577
9578        int build(String[] args, int opti) {
9579            for (; opti<args.length; opti++) {
9580                String name = args[opti];
9581                if ("--".equals(name)) {
9582                    return opti+1;
9583                }
9584                build(name);
9585            }
9586            return opti;
9587        }
9588
9589        boolean match(Object object, ComponentName comp) {
9590            if (all) {
9591                return true;
9592            }
9593            if (components != null) {
9594                for (int i=0; i<components.size(); i++) {
9595                    if (components.get(i).equals(comp)) {
9596                        return true;
9597                    }
9598                }
9599            }
9600            if (objects != null) {
9601                for (int i=0; i<objects.size(); i++) {
9602                    if (System.identityHashCode(object) == objects.get(i)) {
9603                        return true;
9604                    }
9605                }
9606            }
9607            if (strings != null) {
9608                String flat = comp.flattenToString();
9609                for (int i=0; i<strings.size(); i++) {
9610                    if (flat.contains(strings.get(i))) {
9611                        return true;
9612                    }
9613                }
9614            }
9615            return false;
9616        }
9617    }
9618
9619    /**
9620     * There are three things that cmd can be:
9621     *  - a flattened component name that matches an existing activity
9622     *  - the cmd arg isn't the flattened component name of an existing activity:
9623     *    dump all activity whose component contains the cmd as a substring
9624     *  - A hex number of the ActivityRecord object instance.
9625     */
9626    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9627            int opti, boolean dumpAll) {
9628        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9629
9630        if ("all".equals(name)) {
9631            synchronized (this) {
9632                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9633                    activities.add(r1);
9634                }
9635            }
9636        } else if ("top".equals(name)) {
9637            synchronized (this) {
9638                final int N = mMainStack.mHistory.size();
9639                if (N > 0) {
9640                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9641                }
9642            }
9643        } else {
9644            ItemMatcher matcher = new ItemMatcher();
9645            matcher.build(name);
9646
9647            synchronized (this) {
9648                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9649                    if (matcher.match(r1, r1.intent.getComponent())) {
9650                        activities.add(r1);
9651                    }
9652                }
9653            }
9654        }
9655
9656        if (activities.size() <= 0) {
9657            return false;
9658        }
9659
9660        String[] newArgs = new String[args.length - opti];
9661        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9662
9663        TaskRecord lastTask = null;
9664        boolean needSep = false;
9665        for (int i=activities.size()-1; i>=0; i--) {
9666            ActivityRecord r = (ActivityRecord)activities.get(i);
9667            if (needSep) {
9668                pw.println();
9669            }
9670            needSep = true;
9671            synchronized (this) {
9672                if (lastTask != r.task) {
9673                    lastTask = r.task;
9674                    pw.print("TASK "); pw.print(lastTask.affinity);
9675                            pw.print(" id="); pw.println(lastTask.taskId);
9676                    if (dumpAll) {
9677                        lastTask.dump(pw, "  ");
9678                    }
9679                }
9680            }
9681            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9682        }
9683        return true;
9684    }
9685
9686    /**
9687     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9688     * there is a thread associated with the activity.
9689     */
9690    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9691            final ActivityRecord r, String[] args, boolean dumpAll) {
9692        String innerPrefix = prefix + "  ";
9693        synchronized (this) {
9694            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9695                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9696                    pw.print(" pid=");
9697                    if (r.app != null) pw.println(r.app.pid);
9698                    else pw.println("(not running)");
9699            if (dumpAll) {
9700                r.dump(pw, innerPrefix);
9701            }
9702        }
9703        if (r.app != null && r.app.thread != null) {
9704            // flush anything that is already in the PrintWriter since the thread is going
9705            // to write to the file descriptor directly
9706            pw.flush();
9707            try {
9708                TransferPipe tp = new TransferPipe();
9709                try {
9710                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9711                            r.appToken, innerPrefix, args);
9712                    tp.go(fd);
9713                } finally {
9714                    tp.kill();
9715                }
9716            } catch (IOException e) {
9717                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9718            } catch (RemoteException e) {
9719                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9720            }
9721        }
9722    }
9723
9724    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9725            int opti, boolean dumpAll, String dumpPackage) {
9726        boolean needSep = false;
9727        boolean onlyHistory = false;
9728
9729        if ("history".equals(dumpPackage)) {
9730            if (opti < args.length && "-s".equals(args[opti])) {
9731                dumpAll = false;
9732            }
9733            onlyHistory = true;
9734            dumpPackage = null;
9735        }
9736
9737        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9738        if (!onlyHistory && dumpAll) {
9739            if (mRegisteredReceivers.size() > 0) {
9740                boolean printed = false;
9741                Iterator it = mRegisteredReceivers.values().iterator();
9742                while (it.hasNext()) {
9743                    ReceiverList r = (ReceiverList)it.next();
9744                    if (dumpPackage != null && (r.app == null ||
9745                            !dumpPackage.equals(r.app.info.packageName))) {
9746                        continue;
9747                    }
9748                    if (!printed) {
9749                        pw.println("  Registered Receivers:");
9750                        needSep = true;
9751                        printed = true;
9752                    }
9753                    pw.print("  * "); pw.println(r);
9754                    r.dump(pw, "    ");
9755                }
9756            }
9757
9758            if (mReceiverResolver.dump(pw, needSep ?
9759                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9760                    "    ", dumpPackage, false)) {
9761                needSep = true;
9762            }
9763        }
9764
9765        for (BroadcastQueue q : mBroadcastQueues) {
9766            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9767        }
9768
9769        needSep = true;
9770
9771        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9772            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9773                if (needSep) {
9774                    pw.println();
9775                }
9776                needSep = true;
9777                pw.print("  Sticky broadcasts for user ");
9778                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9779                StringBuilder sb = new StringBuilder(128);
9780                for (Map.Entry<String, ArrayList<Intent>> ent
9781                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9782                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9783                    if (dumpAll) {
9784                        pw.println(":");
9785                        ArrayList<Intent> intents = ent.getValue();
9786                        final int N = intents.size();
9787                        for (int i=0; i<N; i++) {
9788                            sb.setLength(0);
9789                            sb.append("    Intent: ");
9790                            intents.get(i).toShortString(sb, false, true, false, false);
9791                            pw.println(sb.toString());
9792                            Bundle bundle = intents.get(i).getExtras();
9793                            if (bundle != null) {
9794                                pw.print("      ");
9795                                pw.println(bundle.toString());
9796                            }
9797                        }
9798                    } else {
9799                        pw.println("");
9800                    }
9801                }
9802            }
9803        }
9804
9805        if (!onlyHistory && dumpAll) {
9806            pw.println();
9807            for (BroadcastQueue queue : mBroadcastQueues) {
9808                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9809                        + queue.mBroadcastsScheduled);
9810            }
9811            pw.println("  mHandler:");
9812            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9813            needSep = true;
9814        }
9815
9816        return needSep;
9817    }
9818
9819    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9820            int opti, boolean dumpAll, String dumpPackage) {
9821        boolean needSep = true;
9822
9823        ItemMatcher matcher = new ItemMatcher();
9824        matcher.build(args, opti);
9825
9826        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9827
9828        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9829
9830        if (mLaunchingProviders.size() > 0) {
9831            boolean printed = false;
9832            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9833                ContentProviderRecord r = mLaunchingProviders.get(i);
9834                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9835                    continue;
9836                }
9837                if (!printed) {
9838                    if (needSep) pw.println(" ");
9839                    needSep = true;
9840                    pw.println("  Launching content providers:");
9841                    printed = true;
9842                }
9843                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9844                        pw.println(r);
9845            }
9846        }
9847
9848        if (mGrantedUriPermissions.size() > 0) {
9849            if (needSep) pw.println();
9850            needSep = true;
9851            pw.println("Granted Uri Permissions:");
9852            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9853                int uid = mGrantedUriPermissions.keyAt(i);
9854                HashMap<Uri, UriPermission> perms
9855                        = mGrantedUriPermissions.valueAt(i);
9856                pw.print("  * UID "); pw.print(uid);
9857                        pw.println(" holds:");
9858                for (UriPermission perm : perms.values()) {
9859                    pw.print("    "); pw.println(perm);
9860                    if (dumpAll) {
9861                        perm.dump(pw, "      ");
9862                    }
9863                }
9864            }
9865            needSep = true;
9866        }
9867
9868        return needSep;
9869    }
9870
9871    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9872            int opti, boolean dumpAll, String dumpPackage) {
9873        boolean needSep = false;
9874
9875        if (mIntentSenderRecords.size() > 0) {
9876            boolean printed = false;
9877            Iterator<WeakReference<PendingIntentRecord>> it
9878                    = mIntentSenderRecords.values().iterator();
9879            while (it.hasNext()) {
9880                WeakReference<PendingIntentRecord> ref = it.next();
9881                PendingIntentRecord rec = ref != null ? ref.get(): null;
9882                if (dumpPackage != null && (rec == null
9883                        || !dumpPackage.equals(rec.key.packageName))) {
9884                    continue;
9885                }
9886                if (!printed) {
9887                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9888                    printed = true;
9889                }
9890                needSep = true;
9891                if (rec != null) {
9892                    pw.print("  * "); pw.println(rec);
9893                    if (dumpAll) {
9894                        rec.dump(pw, "    ");
9895                    }
9896                } else {
9897                    pw.print("  * "); pw.println(ref);
9898                }
9899            }
9900        }
9901
9902        return needSep;
9903    }
9904
9905    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9906            String prefix, String label, boolean complete, boolean brief, boolean client,
9907            String dumpPackage) {
9908        TaskRecord lastTask = null;
9909        boolean needNL = false;
9910        final String innerPrefix = prefix + "      ";
9911        final String[] args = new String[0];
9912        for (int i=list.size()-1; i>=0; i--) {
9913            final ActivityRecord r = (ActivityRecord)list.get(i);
9914            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9915                continue;
9916            }
9917            final boolean full = !brief && (complete || !r.isInHistory());
9918            if (needNL) {
9919                pw.println(" ");
9920                needNL = false;
9921            }
9922            if (lastTask != r.task) {
9923                lastTask = r.task;
9924                pw.print(prefix);
9925                pw.print(full ? "* " : "  ");
9926                pw.println(lastTask);
9927                if (full) {
9928                    lastTask.dump(pw, prefix + "  ");
9929                } else if (complete) {
9930                    // Complete + brief == give a summary.  Isn't that obvious?!?
9931                    if (lastTask.intent != null) {
9932                        pw.print(prefix); pw.print("  ");
9933                                pw.println(lastTask.intent.toInsecureStringWithClip());
9934                    }
9935                }
9936            }
9937            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9938            pw.print(" #"); pw.print(i); pw.print(": ");
9939            pw.println(r);
9940            if (full) {
9941                r.dump(pw, innerPrefix);
9942            } else if (complete) {
9943                // Complete + brief == give a summary.  Isn't that obvious?!?
9944                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9945                if (r.app != null) {
9946                    pw.print(innerPrefix); pw.println(r.app);
9947                }
9948            }
9949            if (client && r.app != null && r.app.thread != null) {
9950                // flush anything that is already in the PrintWriter since the thread is going
9951                // to write to the file descriptor directly
9952                pw.flush();
9953                try {
9954                    TransferPipe tp = new TransferPipe();
9955                    try {
9956                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9957                                r.appToken, innerPrefix, args);
9958                        // Short timeout, since blocking here can
9959                        // deadlock with the application.
9960                        tp.go(fd, 2000);
9961                    } finally {
9962                        tp.kill();
9963                    }
9964                } catch (IOException e) {
9965                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9966                } catch (RemoteException e) {
9967                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9968                }
9969                needNL = true;
9970            }
9971        }
9972    }
9973
9974    private static String buildOomTag(String prefix, String space, int val, int base) {
9975        if (val == base) {
9976            if (space == null) return prefix;
9977            return prefix + "  ";
9978        }
9979        return prefix + "+" + Integer.toString(val-base);
9980    }
9981
9982    private static final int dumpProcessList(PrintWriter pw,
9983            ActivityManagerService service, List list,
9984            String prefix, String normalLabel, String persistentLabel,
9985            String dumpPackage) {
9986        int numPers = 0;
9987        final int N = list.size()-1;
9988        for (int i=N; i>=0; i--) {
9989            ProcessRecord r = (ProcessRecord)list.get(i);
9990            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9991                continue;
9992            }
9993            pw.println(String.format("%s%s #%2d: %s",
9994                    prefix, (r.persistent ? persistentLabel : normalLabel),
9995                    i, r.toString()));
9996            if (r.persistent) {
9997                numPers++;
9998            }
9999        }
10000        return numPers;
10001    }
10002
10003    private static final boolean dumpProcessOomList(PrintWriter pw,
10004            ActivityManagerService service, List<ProcessRecord> origList,
10005            String prefix, String normalLabel, String persistentLabel,
10006            boolean inclDetails, String dumpPackage) {
10007
10008        ArrayList<Pair<ProcessRecord, Integer>> list
10009                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10010        for (int i=0; i<origList.size(); i++) {
10011            ProcessRecord r = origList.get(i);
10012            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10013                continue;
10014            }
10015            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10016        }
10017
10018        if (list.size() <= 0) {
10019            return false;
10020        }
10021
10022        Comparator<Pair<ProcessRecord, Integer>> comparator
10023                = new Comparator<Pair<ProcessRecord, Integer>>() {
10024            @Override
10025            public int compare(Pair<ProcessRecord, Integer> object1,
10026                    Pair<ProcessRecord, Integer> object2) {
10027                if (object1.first.setAdj != object2.first.setAdj) {
10028                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10029                }
10030                if (object1.second.intValue() != object2.second.intValue()) {
10031                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10032                }
10033                return 0;
10034            }
10035        };
10036
10037        Collections.sort(list, comparator);
10038
10039        final long curRealtime = SystemClock.elapsedRealtime();
10040        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10041        final long curUptime = SystemClock.uptimeMillis();
10042        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10043
10044        for (int i=list.size()-1; i>=0; i--) {
10045            ProcessRecord r = list.get(i).first;
10046            String oomAdj;
10047            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10048                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10049            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10050                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10051            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10052                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10053            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10054                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10055            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10056                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10057            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10058                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10059            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10060                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10061            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10062                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10063            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10064                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10065            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10066                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10067            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10068                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10069            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10070                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10071            } else {
10072                oomAdj = Integer.toString(r.setAdj);
10073            }
10074            String schedGroup;
10075            switch (r.setSchedGroup) {
10076                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10077                    schedGroup = "B";
10078                    break;
10079                case Process.THREAD_GROUP_DEFAULT:
10080                    schedGroup = "F";
10081                    break;
10082                default:
10083                    schedGroup = Integer.toString(r.setSchedGroup);
10084                    break;
10085            }
10086            String foreground;
10087            if (r.foregroundActivities) {
10088                foreground = "A";
10089            } else if (r.foregroundServices) {
10090                foreground = "S";
10091            } else {
10092                foreground = " ";
10093            }
10094            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10095                    prefix, (r.persistent ? persistentLabel : normalLabel),
10096                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10097                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10098            if (r.adjSource != null || r.adjTarget != null) {
10099                pw.print(prefix);
10100                pw.print("    ");
10101                if (r.adjTarget instanceof ComponentName) {
10102                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10103                } else if (r.adjTarget != null) {
10104                    pw.print(r.adjTarget.toString());
10105                } else {
10106                    pw.print("{null}");
10107                }
10108                pw.print("<=");
10109                if (r.adjSource instanceof ProcessRecord) {
10110                    pw.print("Proc{");
10111                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10112                    pw.println("}");
10113                } else if (r.adjSource != null) {
10114                    pw.println(r.adjSource.toString());
10115                } else {
10116                    pw.println("{null}");
10117                }
10118            }
10119            if (inclDetails) {
10120                pw.print(prefix);
10121                pw.print("    ");
10122                pw.print("oom: max="); pw.print(r.maxAdj);
10123                pw.print(" hidden="); pw.print(r.hiddenAdj);
10124                pw.print(" client="); pw.print(r.clientHiddenAdj);
10125                pw.print(" empty="); pw.print(r.emptyAdj);
10126                pw.print(" curRaw="); pw.print(r.curRawAdj);
10127                pw.print(" setRaw="); pw.print(r.setRawAdj);
10128                pw.print(" cur="); pw.print(r.curAdj);
10129                pw.print(" set="); pw.println(r.setAdj);
10130                pw.print(prefix);
10131                pw.print("    ");
10132                pw.print("keeping="); pw.print(r.keeping);
10133                pw.print(" hidden="); pw.print(r.hidden);
10134                pw.print(" empty="); pw.print(r.empty);
10135                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10136
10137                if (!r.keeping) {
10138                    if (r.lastWakeTime != 0) {
10139                        long wtime;
10140                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10141                        synchronized (stats) {
10142                            wtime = stats.getProcessWakeTime(r.info.uid,
10143                                    r.pid, curRealtime);
10144                        }
10145                        long timeUsed = wtime - r.lastWakeTime;
10146                        pw.print(prefix);
10147                        pw.print("    ");
10148                        pw.print("keep awake over ");
10149                        TimeUtils.formatDuration(realtimeSince, pw);
10150                        pw.print(" used ");
10151                        TimeUtils.formatDuration(timeUsed, pw);
10152                        pw.print(" (");
10153                        pw.print((timeUsed*100)/realtimeSince);
10154                        pw.println("%)");
10155                    }
10156                    if (r.lastCpuTime != 0) {
10157                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10158                        pw.print(prefix);
10159                        pw.print("    ");
10160                        pw.print("run cpu over ");
10161                        TimeUtils.formatDuration(uptimeSince, pw);
10162                        pw.print(" used ");
10163                        TimeUtils.formatDuration(timeUsed, pw);
10164                        pw.print(" (");
10165                        pw.print((timeUsed*100)/uptimeSince);
10166                        pw.println("%)");
10167                    }
10168                }
10169            }
10170        }
10171        return true;
10172    }
10173
10174    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10175        ArrayList<ProcessRecord> procs;
10176        synchronized (this) {
10177            if (args != null && args.length > start
10178                    && args[start].charAt(0) != '-') {
10179                procs = new ArrayList<ProcessRecord>();
10180                int pid = -1;
10181                try {
10182                    pid = Integer.parseInt(args[start]);
10183                } catch (NumberFormatException e) {
10184
10185                }
10186                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10187                    ProcessRecord proc = mLruProcesses.get(i);
10188                    if (proc.pid == pid) {
10189                        procs.add(proc);
10190                    } else if (proc.processName.equals(args[start])) {
10191                        procs.add(proc);
10192                    }
10193                }
10194                if (procs.size() <= 0) {
10195                    pw.println("No process found for: " + args[start]);
10196                    return null;
10197                }
10198            } else {
10199                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10200            }
10201        }
10202        return procs;
10203    }
10204
10205    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10206            PrintWriter pw, String[] args) {
10207        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10208        if (procs == null) {
10209            return;
10210        }
10211
10212        long uptime = SystemClock.uptimeMillis();
10213        long realtime = SystemClock.elapsedRealtime();
10214        pw.println("Applications Graphics Acceleration Info:");
10215        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10216
10217        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10218            ProcessRecord r = procs.get(i);
10219            if (r.thread != null) {
10220                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10221                pw.flush();
10222                try {
10223                    TransferPipe tp = new TransferPipe();
10224                    try {
10225                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10226                        tp.go(fd);
10227                    } finally {
10228                        tp.kill();
10229                    }
10230                } catch (IOException e) {
10231                    pw.println("Failure while dumping the app: " + r);
10232                    pw.flush();
10233                } catch (RemoteException e) {
10234                    pw.println("Got a RemoteException while dumping the app " + r);
10235                    pw.flush();
10236                }
10237            }
10238        }
10239    }
10240
10241    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10242        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10243        if (procs == null) {
10244            return;
10245        }
10246
10247        pw.println("Applications Database Info:");
10248
10249        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10250            ProcessRecord r = procs.get(i);
10251            if (r.thread != null) {
10252                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10253                pw.flush();
10254                try {
10255                    TransferPipe tp = new TransferPipe();
10256                    try {
10257                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10258                        tp.go(fd);
10259                    } finally {
10260                        tp.kill();
10261                    }
10262                } catch (IOException e) {
10263                    pw.println("Failure while dumping the app: " + r);
10264                    pw.flush();
10265                } catch (RemoteException e) {
10266                    pw.println("Got a RemoteException while dumping the app " + r);
10267                    pw.flush();
10268                }
10269            }
10270        }
10271    }
10272
10273    final static class MemItem {
10274        final String label;
10275        final String shortLabel;
10276        final long pss;
10277        final int id;
10278        ArrayList<MemItem> subitems;
10279
10280        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10281            label = _label;
10282            shortLabel = _shortLabel;
10283            pss = _pss;
10284            id = _id;
10285        }
10286    }
10287
10288    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10289            boolean sort) {
10290        if (sort) {
10291            Collections.sort(items, new Comparator<MemItem>() {
10292                @Override
10293                public int compare(MemItem lhs, MemItem rhs) {
10294                    if (lhs.pss < rhs.pss) {
10295                        return 1;
10296                    } else if (lhs.pss > rhs.pss) {
10297                        return -1;
10298                    }
10299                    return 0;
10300                }
10301            });
10302        }
10303
10304        for (int i=0; i<items.size(); i++) {
10305            MemItem mi = items.get(i);
10306            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10307            if (mi.subitems != null) {
10308                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10309            }
10310        }
10311    }
10312
10313    // These are in KB.
10314    static final long[] DUMP_MEM_BUCKETS = new long[] {
10315        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10316        120*1024, 160*1024, 200*1024,
10317        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10318        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10319    };
10320
10321    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10322            boolean stackLike) {
10323        int start = label.lastIndexOf('.');
10324        if (start >= 0) start++;
10325        else start = 0;
10326        int end = label.length();
10327        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10328            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10329                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10330                out.append(bucket);
10331                out.append(stackLike ? "MB." : "MB ");
10332                out.append(label, start, end);
10333                return;
10334            }
10335        }
10336        out.append(memKB/1024);
10337        out.append(stackLike ? "MB." : "MB ");
10338        out.append(label, start, end);
10339    }
10340
10341    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10342            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10343            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10344            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10345            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10346    };
10347    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10348            "System", "Persistent", "Foreground",
10349            "Visible", "Perceptible", "Heavy Weight",
10350            "Backup", "A Services", "Home", "Previous",
10351            "B Services", "Background"
10352    };
10353
10354    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10355            PrintWriter pw, String prefix, String[] args, boolean brief,
10356            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10357        boolean dumpAll = false;
10358        boolean oomOnly = false;
10359
10360        int opti = 0;
10361        while (opti < args.length) {
10362            String opt = args[opti];
10363            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10364                break;
10365            }
10366            opti++;
10367            if ("-a".equals(opt)) {
10368                dumpAll = true;
10369            } else if ("--oom".equals(opt)) {
10370                oomOnly = true;
10371            } else if ("-h".equals(opt)) {
10372                pw.println("meminfo dump options: [-a] [--oom] [process]");
10373                pw.println("  -a: include all available information for each process.");
10374                pw.println("  --oom: only show processes organized by oom adj.");
10375                pw.println("If [process] is specified it can be the name or ");
10376                pw.println("pid of a specific process to dump.");
10377                return;
10378            } else {
10379                pw.println("Unknown argument: " + opt + "; use -h for help");
10380            }
10381        }
10382
10383        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10384        if (procs == null) {
10385            return;
10386        }
10387
10388        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10389        long uptime = SystemClock.uptimeMillis();
10390        long realtime = SystemClock.elapsedRealtime();
10391
10392        if (procs.size() == 1 || isCheckinRequest) {
10393            dumpAll = true;
10394        }
10395
10396        if (isCheckinRequest) {
10397            // short checkin version
10398            pw.println(uptime + "," + realtime);
10399            pw.flush();
10400        } else {
10401            pw.println("Applications Memory Usage (kB):");
10402            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10403        }
10404
10405        String[] innerArgs = new String[args.length-opti];
10406        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10407
10408        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10409        long nativePss=0, dalvikPss=0, otherPss=0;
10410        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10411
10412        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10413        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10414                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10415
10416        long totalPss = 0;
10417
10418        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10419            ProcessRecord r = procs.get(i);
10420            if (r.thread != null) {
10421                if (!isCheckinRequest && dumpAll) {
10422                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10423                    pw.flush();
10424                }
10425                Debug.MemoryInfo mi = null;
10426                if (dumpAll) {
10427                    try {
10428                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10429                    } catch (RemoteException e) {
10430                        if (!isCheckinRequest) {
10431                            pw.println("Got RemoteException!");
10432                            pw.flush();
10433                        }
10434                    }
10435                } else {
10436                    mi = new Debug.MemoryInfo();
10437                    Debug.getMemoryInfo(r.pid, mi);
10438                }
10439
10440                if (!isCheckinRequest && mi != null) {
10441                    long myTotalPss = mi.getTotalPss();
10442                    totalPss += myTotalPss;
10443                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10444                            r.processName, myTotalPss, 0);
10445                    procMems.add(pssItem);
10446
10447                    nativePss += mi.nativePss;
10448                    dalvikPss += mi.dalvikPss;
10449                    otherPss += mi.otherPss;
10450                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10451                        long mem = mi.getOtherPss(j);
10452                        miscPss[j] += mem;
10453                        otherPss -= mem;
10454                    }
10455
10456                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10457                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10458                                || oomIndex == (oomPss.length-1)) {
10459                            oomPss[oomIndex] += myTotalPss;
10460                            if (oomProcs[oomIndex] == null) {
10461                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10462                            }
10463                            oomProcs[oomIndex].add(pssItem);
10464                            break;
10465                        }
10466                    }
10467                }
10468            }
10469        }
10470
10471        if (!isCheckinRequest && procs.size() > 1) {
10472            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10473
10474            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10475            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10476            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10477            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10478                String label = Debug.MemoryInfo.getOtherLabel(j);
10479                catMems.add(new MemItem(label, label, miscPss[j], j));
10480            }
10481
10482            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10483            for (int j=0; j<oomPss.length; j++) {
10484                if (oomPss[j] != 0) {
10485                    String label = DUMP_MEM_OOM_LABEL[j];
10486                    MemItem item = new MemItem(label, label, oomPss[j],
10487                            DUMP_MEM_OOM_ADJ[j]);
10488                    item.subitems = oomProcs[j];
10489                    oomMems.add(item);
10490                }
10491            }
10492
10493            if (outTag != null || outStack != null) {
10494                if (outTag != null) {
10495                    appendMemBucket(outTag, totalPss, "total", false);
10496                }
10497                if (outStack != null) {
10498                    appendMemBucket(outStack, totalPss, "total", true);
10499                }
10500                boolean firstLine = true;
10501                for (int i=0; i<oomMems.size(); i++) {
10502                    MemItem miCat = oomMems.get(i);
10503                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10504                        continue;
10505                    }
10506                    if (miCat.id < ProcessList.SERVICE_ADJ
10507                            || miCat.id == ProcessList.HOME_APP_ADJ
10508                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10509                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10510                            outTag.append(" / ");
10511                        }
10512                        if (outStack != null) {
10513                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10514                                if (firstLine) {
10515                                    outStack.append(":");
10516                                    firstLine = false;
10517                                }
10518                                outStack.append("\n\t at ");
10519                            } else {
10520                                outStack.append("$");
10521                            }
10522                        }
10523                        for (int j=0; j<miCat.subitems.size(); j++) {
10524                            MemItem mi = miCat.subitems.get(j);
10525                            if (j > 0) {
10526                                if (outTag != null) {
10527                                    outTag.append(" ");
10528                                }
10529                                if (outStack != null) {
10530                                    outStack.append("$");
10531                                }
10532                            }
10533                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10534                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10535                            }
10536                            if (outStack != null) {
10537                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10538                            }
10539                        }
10540                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10541                            outStack.append("(");
10542                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10543                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10544                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10545                                    outStack.append(":");
10546                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10547                                }
10548                            }
10549                            outStack.append(")");
10550                        }
10551                    }
10552                }
10553            }
10554
10555            if (!brief && !oomOnly) {
10556                pw.println();
10557                pw.println("Total PSS by process:");
10558                dumpMemItems(pw, "  ", procMems, true);
10559                pw.println();
10560            }
10561            pw.println("Total PSS by OOM adjustment:");
10562            dumpMemItems(pw, "  ", oomMems, false);
10563            if (!oomOnly) {
10564                PrintWriter out = categoryPw != null ? categoryPw : pw;
10565                out.println();
10566                out.println("Total PSS by category:");
10567                dumpMemItems(out, "  ", catMems, true);
10568            }
10569            pw.println();
10570            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10571            final int[] SINGLE_LONG_FORMAT = new int[] {
10572                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10573            };
10574            long[] longOut = new long[1];
10575            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10576                    SINGLE_LONG_FORMAT, null, longOut, null);
10577            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10578            longOut[0] = 0;
10579            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10580                    SINGLE_LONG_FORMAT, null, longOut, null);
10581            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10582            longOut[0] = 0;
10583            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10584                    SINGLE_LONG_FORMAT, null, longOut, null);
10585            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10586            longOut[0] = 0;
10587            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10588                    SINGLE_LONG_FORMAT, null, longOut, null);
10589            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10590            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10591                    pw.print(shared); pw.println(" kB");
10592            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10593                    pw.print(voltile); pw.println(" kB volatile");
10594        }
10595    }
10596
10597    /**
10598     * Searches array of arguments for the specified string
10599     * @param args array of argument strings
10600     * @param value value to search for
10601     * @return true if the value is contained in the array
10602     */
10603    private static boolean scanArgs(String[] args, String value) {
10604        if (args != null) {
10605            for (String arg : args) {
10606                if (value.equals(arg)) {
10607                    return true;
10608                }
10609            }
10610        }
10611        return false;
10612    }
10613
10614    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10615            ContentProviderRecord cpr, boolean always) {
10616        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10617
10618        if (!inLaunching || always) {
10619            synchronized (cpr) {
10620                cpr.launchingApp = null;
10621                cpr.notifyAll();
10622            }
10623            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10624            String names[] = cpr.info.authority.split(";");
10625            for (int j = 0; j < names.length; j++) {
10626                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10627            }
10628        }
10629
10630        for (int i=0; i<cpr.connections.size(); i++) {
10631            ContentProviderConnection conn = cpr.connections.get(i);
10632            if (conn.waiting) {
10633                // If this connection is waiting for the provider, then we don't
10634                // need to mess with its process unless we are always removing
10635                // or for some reason the provider is not currently launching.
10636                if (inLaunching && !always) {
10637                    continue;
10638                }
10639            }
10640            ProcessRecord capp = conn.client;
10641            conn.dead = true;
10642            if (conn.stableCount > 0) {
10643                if (!capp.persistent && capp.thread != null
10644                        && capp.pid != 0
10645                        && capp.pid != MY_PID) {
10646                    Slog.i(TAG, "Kill " + capp.processName
10647                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10648                            + " in dying process " + (proc != null ? proc.processName : "??"));
10649                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10650                            capp.processName, capp.setAdj, "dying provider "
10651                                    + cpr.name.toShortString());
10652                    Process.killProcessQuiet(capp.pid);
10653                }
10654            } else if (capp.thread != null && conn.provider.provider != null) {
10655                try {
10656                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10657                } catch (RemoteException e) {
10658                }
10659                // In the protocol here, we don't expect the client to correctly
10660                // clean up this connection, we'll just remove it.
10661                cpr.connections.remove(i);
10662                conn.client.conProviders.remove(conn);
10663            }
10664        }
10665
10666        if (inLaunching && always) {
10667            mLaunchingProviders.remove(cpr);
10668        }
10669        return inLaunching;
10670    }
10671
10672    /**
10673     * Main code for cleaning up a process when it has gone away.  This is
10674     * called both as a result of the process dying, or directly when stopping
10675     * a process when running in single process mode.
10676     */
10677    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10678            boolean restarting, boolean allowRestart, int index) {
10679        if (index >= 0) {
10680            mLruProcesses.remove(index);
10681        }
10682
10683        mProcessesToGc.remove(app);
10684
10685        // Dismiss any open dialogs.
10686        if (app.crashDialog != null) {
10687            app.crashDialog.dismiss();
10688            app.crashDialog = null;
10689        }
10690        if (app.anrDialog != null) {
10691            app.anrDialog.dismiss();
10692            app.anrDialog = null;
10693        }
10694        if (app.waitDialog != null) {
10695            app.waitDialog.dismiss();
10696            app.waitDialog = null;
10697        }
10698
10699        app.crashing = false;
10700        app.notResponding = false;
10701
10702        app.resetPackageList();
10703        app.unlinkDeathRecipient();
10704        app.thread = null;
10705        app.forcingToForeground = null;
10706        app.foregroundServices = false;
10707        app.foregroundActivities = false;
10708        app.hasShownUi = false;
10709        app.hasAboveClient = false;
10710
10711        mServices.killServicesLocked(app, allowRestart);
10712
10713        boolean restart = false;
10714
10715        // Remove published content providers.
10716        if (!app.pubProviders.isEmpty()) {
10717            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10718            while (it.hasNext()) {
10719                ContentProviderRecord cpr = it.next();
10720
10721                final boolean always = app.bad || !allowRestart;
10722                if (removeDyingProviderLocked(app, cpr, always) || always) {
10723                    // We left the provider in the launching list, need to
10724                    // restart it.
10725                    restart = true;
10726                }
10727
10728                cpr.provider = null;
10729                cpr.proc = null;
10730            }
10731            app.pubProviders.clear();
10732        }
10733
10734        // Take care of any launching providers waiting for this process.
10735        if (checkAppInLaunchingProvidersLocked(app, false)) {
10736            restart = true;
10737        }
10738
10739        // Unregister from connected content providers.
10740        if (!app.conProviders.isEmpty()) {
10741            for (int i=0; i<app.conProviders.size(); i++) {
10742                ContentProviderConnection conn = app.conProviders.get(i);
10743                conn.provider.connections.remove(conn);
10744            }
10745            app.conProviders.clear();
10746        }
10747
10748        // At this point there may be remaining entries in mLaunchingProviders
10749        // where we were the only one waiting, so they are no longer of use.
10750        // Look for these and clean up if found.
10751        // XXX Commented out for now.  Trying to figure out a way to reproduce
10752        // the actual situation to identify what is actually going on.
10753        if (false) {
10754            for (int i=0; i<mLaunchingProviders.size(); i++) {
10755                ContentProviderRecord cpr = (ContentProviderRecord)
10756                        mLaunchingProviders.get(i);
10757                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10758                    synchronized (cpr) {
10759                        cpr.launchingApp = null;
10760                        cpr.notifyAll();
10761                    }
10762                }
10763            }
10764        }
10765
10766        skipCurrentReceiverLocked(app);
10767
10768        // Unregister any receivers.
10769        if (app.receivers.size() > 0) {
10770            Iterator<ReceiverList> it = app.receivers.iterator();
10771            while (it.hasNext()) {
10772                removeReceiverLocked(it.next());
10773            }
10774            app.receivers.clear();
10775        }
10776
10777        // If the app is undergoing backup, tell the backup manager about it
10778        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10779            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10780                    + mBackupTarget.appInfo + " died during backup");
10781            try {
10782                IBackupManager bm = IBackupManager.Stub.asInterface(
10783                        ServiceManager.getService(Context.BACKUP_SERVICE));
10784                bm.agentDisconnected(app.info.packageName);
10785            } catch (RemoteException e) {
10786                // can't happen; backup manager is local
10787            }
10788        }
10789
10790        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10791            ProcessChangeItem item = mPendingProcessChanges.get(i);
10792            if (item.pid == app.pid) {
10793                mPendingProcessChanges.remove(i);
10794                mAvailProcessChanges.add(item);
10795            }
10796        }
10797        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10798
10799        // If the caller is restarting this app, then leave it in its
10800        // current lists and let the caller take care of it.
10801        if (restarting) {
10802            return;
10803        }
10804
10805        if (!app.persistent || app.isolated) {
10806            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10807                    "Removing non-persistent process during cleanup: " + app);
10808            mProcessNames.remove(app.processName, app.uid);
10809            mIsolatedProcesses.remove(app.uid);
10810            if (mHeavyWeightProcess == app) {
10811                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10812                        mHeavyWeightProcess.userId, 0));
10813                mHeavyWeightProcess = null;
10814            }
10815        } else if (!app.removed) {
10816            // This app is persistent, so we need to keep its record around.
10817            // If it is not already on the pending app list, add it there
10818            // and start a new process for it.
10819            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10820                mPersistentStartingProcesses.add(app);
10821                restart = true;
10822            }
10823        }
10824        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10825                "Clean-up removing on hold: " + app);
10826        mProcessesOnHold.remove(app);
10827
10828        if (app == mHomeProcess) {
10829            mHomeProcess = null;
10830        }
10831        if (app == mPreviousProcess) {
10832            mPreviousProcess = null;
10833        }
10834
10835        if (restart && !app.isolated) {
10836            // We have components that still need to be running in the
10837            // process, so re-launch it.
10838            mProcessNames.put(app.processName, app.uid, app);
10839            startProcessLocked(app, "restart", app.processName);
10840        } else if (app.pid > 0 && app.pid != MY_PID) {
10841            // Goodbye!
10842            synchronized (mPidsSelfLocked) {
10843                mPidsSelfLocked.remove(app.pid);
10844                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10845            }
10846            app.setPid(0);
10847        }
10848    }
10849
10850    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10851        // Look through the content providers we are waiting to have launched,
10852        // and if any run in this process then either schedule a restart of
10853        // the process or kill the client waiting for it if this process has
10854        // gone bad.
10855        int NL = mLaunchingProviders.size();
10856        boolean restart = false;
10857        for (int i=0; i<NL; i++) {
10858            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10859            if (cpr.launchingApp == app) {
10860                if (!alwaysBad && !app.bad) {
10861                    restart = true;
10862                } else {
10863                    removeDyingProviderLocked(app, cpr, true);
10864                    // cpr should have been removed from mLaunchingProviders
10865                    NL = mLaunchingProviders.size();
10866                    i--;
10867                }
10868            }
10869        }
10870        return restart;
10871    }
10872
10873    // =========================================================
10874    // SERVICES
10875    // =========================================================
10876
10877    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10878            int flags) {
10879        enforceNotIsolatedCaller("getServices");
10880        synchronized (this) {
10881            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10882        }
10883    }
10884
10885    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10886        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10887        synchronized (this) {
10888            return mServices.getRunningServiceControlPanelLocked(name);
10889        }
10890    }
10891
10892    public ComponentName startService(IApplicationThread caller, Intent service,
10893            String resolvedType, int userId) {
10894        enforceNotIsolatedCaller("startService");
10895        // Refuse possible leaked file descriptors
10896        if (service != null && service.hasFileDescriptors() == true) {
10897            throw new IllegalArgumentException("File descriptors passed in Intent");
10898        }
10899
10900        if (DEBUG_SERVICE)
10901            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10902        synchronized(this) {
10903            final int callingPid = Binder.getCallingPid();
10904            final int callingUid = Binder.getCallingUid();
10905            checkValidCaller(callingUid, userId);
10906            final long origId = Binder.clearCallingIdentity();
10907            ComponentName res = mServices.startServiceLocked(caller, service,
10908                    resolvedType, callingPid, callingUid, userId);
10909            Binder.restoreCallingIdentity(origId);
10910            return res;
10911        }
10912    }
10913
10914    ComponentName startServiceInPackage(int uid,
10915            Intent service, String resolvedType, int userId) {
10916        synchronized(this) {
10917            if (DEBUG_SERVICE)
10918                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10919            final long origId = Binder.clearCallingIdentity();
10920            ComponentName res = mServices.startServiceLocked(null, service,
10921                    resolvedType, -1, uid, userId);
10922            Binder.restoreCallingIdentity(origId);
10923            return res;
10924        }
10925    }
10926
10927    public int stopService(IApplicationThread caller, Intent service,
10928            String resolvedType, int userId) {
10929        enforceNotIsolatedCaller("stopService");
10930        // Refuse possible leaked file descriptors
10931        if (service != null && service.hasFileDescriptors() == true) {
10932            throw new IllegalArgumentException("File descriptors passed in Intent");
10933        }
10934
10935        checkValidCaller(Binder.getCallingUid(), userId);
10936
10937        synchronized(this) {
10938            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10939        }
10940    }
10941
10942    public IBinder peekService(Intent service, String resolvedType) {
10943        enforceNotIsolatedCaller("peekService");
10944        // Refuse possible leaked file descriptors
10945        if (service != null && service.hasFileDescriptors() == true) {
10946            throw new IllegalArgumentException("File descriptors passed in Intent");
10947        }
10948        synchronized(this) {
10949            return mServices.peekServiceLocked(service, resolvedType);
10950        }
10951    }
10952
10953    public boolean stopServiceToken(ComponentName className, IBinder token,
10954            int startId) {
10955        synchronized(this) {
10956            return mServices.stopServiceTokenLocked(className, token, startId);
10957        }
10958    }
10959
10960    public void setServiceForeground(ComponentName className, IBinder token,
10961            int id, Notification notification, boolean removeNotification) {
10962        synchronized(this) {
10963            mServices.setServiceForegroundLocked(className, token, id, notification,
10964                    removeNotification);
10965        }
10966    }
10967
10968    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10969            boolean requireFull, String name, String callerPackage) {
10970        final int callingUserId = UserHandle.getUserId(callingUid);
10971        if (callingUserId != userId) {
10972            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10973                if ((requireFull || checkComponentPermission(
10974                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10975                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10976                        && checkComponentPermission(
10977                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10978                                callingPid, callingUid, -1, true)
10979                                != PackageManager.PERMISSION_GRANTED) {
10980                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10981                        // In this case, they would like to just execute as their
10982                        // owner user instead of failing.
10983                        userId = callingUserId;
10984                    } else {
10985                        StringBuilder builder = new StringBuilder(128);
10986                        builder.append("Permission Denial: ");
10987                        builder.append(name);
10988                        if (callerPackage != null) {
10989                            builder.append(" from ");
10990                            builder.append(callerPackage);
10991                        }
10992                        builder.append(" asks to run as user ");
10993                        builder.append(userId);
10994                        builder.append(" but is calling from user ");
10995                        builder.append(UserHandle.getUserId(callingUid));
10996                        builder.append("; this requires ");
10997                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10998                        if (!requireFull) {
10999                            builder.append(" or ");
11000                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11001                        }
11002                        String msg = builder.toString();
11003                        Slog.w(TAG, msg);
11004                        throw new SecurityException(msg);
11005                    }
11006                }
11007            }
11008            if (userId == UserHandle.USER_CURRENT
11009                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
11010                // Note that we may be accessing this outside of a lock...
11011                // shouldn't be a big deal, if this is being called outside
11012                // of a locked context there is intrinsically a race with
11013                // the value the caller will receive and someone else changing it.
11014                userId = mCurrentUserId;
11015            }
11016            if (!allowAll && userId < 0) {
11017                throw new IllegalArgumentException(
11018                        "Call does not support special user #" + userId);
11019            }
11020        }
11021        return userId;
11022    }
11023
11024    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11025            String className, int flags) {
11026        boolean result = false;
11027        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11028            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11029                if (ActivityManager.checkUidPermission(
11030                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11031                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11032                    ComponentName comp = new ComponentName(aInfo.packageName, className);
11033                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
11034                            + " requests FLAG_SINGLE_USER, but app does not hold "
11035                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11036                    Slog.w(TAG, msg);
11037                    throw new SecurityException(msg);
11038                }
11039                result = true;
11040            }
11041        } else if (componentProcessName == aInfo.packageName) {
11042            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11043        } else if ("system".equals(componentProcessName)) {
11044            result = true;
11045        }
11046        if (DEBUG_MU) {
11047            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11048                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11049        }
11050        return result;
11051    }
11052
11053    public int bindService(IApplicationThread caller, IBinder token,
11054            Intent service, String resolvedType,
11055            IServiceConnection connection, int flags, int userId) {
11056        enforceNotIsolatedCaller("bindService");
11057        // Refuse possible leaked file descriptors
11058        if (service != null && service.hasFileDescriptors() == true) {
11059            throw new IllegalArgumentException("File descriptors passed in Intent");
11060        }
11061
11062        synchronized(this) {
11063            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11064                    connection, flags, userId);
11065        }
11066    }
11067
11068    public boolean unbindService(IServiceConnection connection) {
11069        synchronized (this) {
11070            return mServices.unbindServiceLocked(connection);
11071        }
11072    }
11073
11074    public void publishService(IBinder token, Intent intent, IBinder service) {
11075        // Refuse possible leaked file descriptors
11076        if (intent != null && intent.hasFileDescriptors() == true) {
11077            throw new IllegalArgumentException("File descriptors passed in Intent");
11078        }
11079
11080        synchronized(this) {
11081            if (!(token instanceof ServiceRecord)) {
11082                throw new IllegalArgumentException("Invalid service token");
11083            }
11084            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11085        }
11086    }
11087
11088    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11089        // Refuse possible leaked file descriptors
11090        if (intent != null && intent.hasFileDescriptors() == true) {
11091            throw new IllegalArgumentException("File descriptors passed in Intent");
11092        }
11093
11094        synchronized(this) {
11095            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11096        }
11097    }
11098
11099    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11100        synchronized(this) {
11101            if (!(token instanceof ServiceRecord)) {
11102                throw new IllegalArgumentException("Invalid service token");
11103            }
11104            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11105        }
11106    }
11107
11108    // =========================================================
11109    // BACKUP AND RESTORE
11110    // =========================================================
11111
11112    // Cause the target app to be launched if necessary and its backup agent
11113    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11114    // activity manager to announce its creation.
11115    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11116        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11117        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11118
11119        synchronized(this) {
11120            // !!! TODO: currently no check here that we're already bound
11121            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11122            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11123            synchronized (stats) {
11124                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11125            }
11126
11127            // Backup agent is now in use, its package can't be stopped.
11128            try {
11129                AppGlobals.getPackageManager().setPackageStoppedState(
11130                        app.packageName, false, UserHandle.getUserId(app.uid));
11131            } catch (RemoteException e) {
11132            } catch (IllegalArgumentException e) {
11133                Slog.w(TAG, "Failed trying to unstop package "
11134                        + app.packageName + ": " + e);
11135            }
11136
11137            BackupRecord r = new BackupRecord(ss, app, backupMode);
11138            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11139                    ? new ComponentName(app.packageName, app.backupAgentName)
11140                    : new ComponentName("android", "FullBackupAgent");
11141            // startProcessLocked() returns existing proc's record if it's already running
11142            ProcessRecord proc = startProcessLocked(app.processName, app,
11143                    false, 0, "backup", hostingName, false, false);
11144            if (proc == null) {
11145                Slog.e(TAG, "Unable to start backup agent process " + r);
11146                return false;
11147            }
11148
11149            r.app = proc;
11150            mBackupTarget = r;
11151            mBackupAppName = app.packageName;
11152
11153            // Try not to kill the process during backup
11154            updateOomAdjLocked(proc);
11155
11156            // If the process is already attached, schedule the creation of the backup agent now.
11157            // If it is not yet live, this will be done when it attaches to the framework.
11158            if (proc.thread != null) {
11159                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11160                try {
11161                    proc.thread.scheduleCreateBackupAgent(app,
11162                            compatibilityInfoForPackageLocked(app), backupMode);
11163                } catch (RemoteException e) {
11164                    // Will time out on the backup manager side
11165                }
11166            } else {
11167                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11168            }
11169            // Invariants: at this point, the target app process exists and the application
11170            // is either already running or in the process of coming up.  mBackupTarget and
11171            // mBackupAppName describe the app, so that when it binds back to the AM we
11172            // know that it's scheduled for a backup-agent operation.
11173        }
11174
11175        return true;
11176    }
11177
11178    // A backup agent has just come up
11179    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11180        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11181                + " = " + agent);
11182
11183        synchronized(this) {
11184            if (!agentPackageName.equals(mBackupAppName)) {
11185                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11186                return;
11187            }
11188        }
11189
11190        long oldIdent = Binder.clearCallingIdentity();
11191        try {
11192            IBackupManager bm = IBackupManager.Stub.asInterface(
11193                    ServiceManager.getService(Context.BACKUP_SERVICE));
11194            bm.agentConnected(agentPackageName, agent);
11195        } catch (RemoteException e) {
11196            // can't happen; the backup manager service is local
11197        } catch (Exception e) {
11198            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11199            e.printStackTrace();
11200        } finally {
11201            Binder.restoreCallingIdentity(oldIdent);
11202        }
11203    }
11204
11205    // done with this agent
11206    public void unbindBackupAgent(ApplicationInfo appInfo) {
11207        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11208        if (appInfo == null) {
11209            Slog.w(TAG, "unbind backup agent for null app");
11210            return;
11211        }
11212
11213        synchronized(this) {
11214            if (mBackupAppName == null) {
11215                Slog.w(TAG, "Unbinding backup agent with no active backup");
11216                return;
11217            }
11218
11219            if (!mBackupAppName.equals(appInfo.packageName)) {
11220                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11221                return;
11222            }
11223
11224            ProcessRecord proc = mBackupTarget.app;
11225            mBackupTarget = null;
11226            mBackupAppName = null;
11227
11228            // Not backing this app up any more; reset its OOM adjustment
11229            updateOomAdjLocked(proc);
11230
11231            // If the app crashed during backup, 'thread' will be null here
11232            if (proc.thread != null) {
11233                try {
11234                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11235                            compatibilityInfoForPackageLocked(appInfo));
11236                } catch (Exception e) {
11237                    Slog.e(TAG, "Exception when unbinding backup agent:");
11238                    e.printStackTrace();
11239                }
11240            }
11241        }
11242    }
11243    // =========================================================
11244    // BROADCASTS
11245    // =========================================================
11246
11247    private final List getStickiesLocked(String action, IntentFilter filter,
11248            List cur, int userId) {
11249        final ContentResolver resolver = mContext.getContentResolver();
11250        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11251        if (stickies == null) {
11252            return cur;
11253        }
11254        final ArrayList<Intent> list = stickies.get(action);
11255        if (list == null) {
11256            return cur;
11257        }
11258        int N = list.size();
11259        for (int i=0; i<N; i++) {
11260            Intent intent = list.get(i);
11261            if (filter.match(resolver, intent, true, TAG) >= 0) {
11262                if (cur == null) {
11263                    cur = new ArrayList<Intent>();
11264                }
11265                cur.add(intent);
11266            }
11267        }
11268        return cur;
11269    }
11270
11271    boolean isPendingBroadcastProcessLocked(int pid) {
11272        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11273                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11274    }
11275
11276    void skipPendingBroadcastLocked(int pid) {
11277            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11278            for (BroadcastQueue queue : mBroadcastQueues) {
11279                queue.skipPendingBroadcastLocked(pid);
11280            }
11281    }
11282
11283    // The app just attached; send any pending broadcasts that it should receive
11284    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11285        boolean didSomething = false;
11286        for (BroadcastQueue queue : mBroadcastQueues) {
11287            didSomething |= queue.sendPendingBroadcastsLocked(app);
11288        }
11289        return didSomething;
11290    }
11291
11292    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11293            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11294        enforceNotIsolatedCaller("registerReceiver");
11295        int callingUid;
11296        int callingPid;
11297        synchronized(this) {
11298            ProcessRecord callerApp = null;
11299            if (caller != null) {
11300                callerApp = getRecordForAppLocked(caller);
11301                if (callerApp == null) {
11302                    throw new SecurityException(
11303                            "Unable to find app for caller " + caller
11304                            + " (pid=" + Binder.getCallingPid()
11305                            + ") when registering receiver " + receiver);
11306                }
11307                if (callerApp.info.uid != Process.SYSTEM_UID &&
11308                        !callerApp.pkgList.contains(callerPackage)) {
11309                    throw new SecurityException("Given caller package " + callerPackage
11310                            + " is not running in process " + callerApp);
11311                }
11312                callingUid = callerApp.info.uid;
11313                callingPid = callerApp.pid;
11314            } else {
11315                callerPackage = null;
11316                callingUid = Binder.getCallingUid();
11317                callingPid = Binder.getCallingPid();
11318            }
11319
11320            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11321                    true, true, "registerReceiver", callerPackage);
11322
11323            List allSticky = null;
11324
11325            // Look for any matching sticky broadcasts...
11326            Iterator actions = filter.actionsIterator();
11327            if (actions != null) {
11328                while (actions.hasNext()) {
11329                    String action = (String)actions.next();
11330                    allSticky = getStickiesLocked(action, filter, allSticky,
11331                            UserHandle.USER_ALL);
11332                    allSticky = getStickiesLocked(action, filter, allSticky,
11333                            UserHandle.getUserId(callingUid));
11334                }
11335            } else {
11336                allSticky = getStickiesLocked(null, filter, allSticky,
11337                        UserHandle.USER_ALL);
11338                allSticky = getStickiesLocked(null, filter, allSticky,
11339                        UserHandle.getUserId(callingUid));
11340            }
11341
11342            // The first sticky in the list is returned directly back to
11343            // the client.
11344            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11345
11346            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11347                    + ": " + sticky);
11348
11349            if (receiver == null) {
11350                return sticky;
11351            }
11352
11353            ReceiverList rl
11354                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11355            if (rl == null) {
11356                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11357                        userId, receiver);
11358                if (rl.app != null) {
11359                    rl.app.receivers.add(rl);
11360                } else {
11361                    try {
11362                        receiver.asBinder().linkToDeath(rl, 0);
11363                    } catch (RemoteException e) {
11364                        return sticky;
11365                    }
11366                    rl.linkedToDeath = true;
11367                }
11368                mRegisteredReceivers.put(receiver.asBinder(), rl);
11369            } else if (rl.uid != callingUid) {
11370                throw new IllegalArgumentException(
11371                        "Receiver requested to register for uid " + callingUid
11372                        + " was previously registered for uid " + rl.uid);
11373            } else if (rl.pid != callingPid) {
11374                throw new IllegalArgumentException(
11375                        "Receiver requested to register for pid " + callingPid
11376                        + " was previously registered for pid " + rl.pid);
11377            } else if (rl.userId != userId) {
11378                throw new IllegalArgumentException(
11379                        "Receiver requested to register for user " + userId
11380                        + " was previously registered for user " + rl.userId);
11381            }
11382            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11383                    permission, callingUid, userId);
11384            rl.add(bf);
11385            if (!bf.debugCheck()) {
11386                Slog.w(TAG, "==> For Dynamic broadast");
11387            }
11388            mReceiverResolver.addFilter(bf);
11389
11390            // Enqueue broadcasts for all existing stickies that match
11391            // this filter.
11392            if (allSticky != null) {
11393                ArrayList receivers = new ArrayList();
11394                receivers.add(bf);
11395
11396                int N = allSticky.size();
11397                for (int i=0; i<N; i++) {
11398                    Intent intent = (Intent)allSticky.get(i);
11399                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11400                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11401                            null, -1, -1, null, receivers, null, 0, null, null,
11402                            false, true, true, -1);
11403                    queue.enqueueParallelBroadcastLocked(r);
11404                    queue.scheduleBroadcastsLocked();
11405                }
11406            }
11407
11408            return sticky;
11409        }
11410    }
11411
11412    public void unregisterReceiver(IIntentReceiver receiver) {
11413        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11414
11415        final long origId = Binder.clearCallingIdentity();
11416        try {
11417            boolean doTrim = false;
11418
11419            synchronized(this) {
11420                ReceiverList rl
11421                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11422                if (rl != null) {
11423                    if (rl.curBroadcast != null) {
11424                        BroadcastRecord r = rl.curBroadcast;
11425                        final boolean doNext = finishReceiverLocked(
11426                                receiver.asBinder(), r.resultCode, r.resultData,
11427                                r.resultExtras, r.resultAbort, true);
11428                        if (doNext) {
11429                            doTrim = true;
11430                            r.queue.processNextBroadcast(false);
11431                        }
11432                    }
11433
11434                    if (rl.app != null) {
11435                        rl.app.receivers.remove(rl);
11436                    }
11437                    removeReceiverLocked(rl);
11438                    if (rl.linkedToDeath) {
11439                        rl.linkedToDeath = false;
11440                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11441                    }
11442                }
11443            }
11444
11445            // If we actually concluded any broadcasts, we might now be able
11446            // to trim the recipients' apps from our working set
11447            if (doTrim) {
11448                trimApplications();
11449                return;
11450            }
11451
11452        } finally {
11453            Binder.restoreCallingIdentity(origId);
11454        }
11455    }
11456
11457    void removeReceiverLocked(ReceiverList rl) {
11458        mRegisteredReceivers.remove(rl.receiver.asBinder());
11459        int N = rl.size();
11460        for (int i=0; i<N; i++) {
11461            mReceiverResolver.removeFilter(rl.get(i));
11462        }
11463    }
11464
11465    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11466        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11467            ProcessRecord r = mLruProcesses.get(i);
11468            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11469                try {
11470                    r.thread.dispatchPackageBroadcast(cmd, packages);
11471                } catch (RemoteException ex) {
11472                }
11473            }
11474        }
11475    }
11476
11477    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11478            int[] users) {
11479        List<ResolveInfo> receivers = null;
11480        try {
11481            HashSet<ComponentName> singleUserReceivers = null;
11482            boolean scannedFirstReceivers = false;
11483            for (int user : users) {
11484                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11485                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11486                if (user != 0 && newReceivers != null) {
11487                    // If this is not the primary user, we need to check for
11488                    // any receivers that should be filtered out.
11489                    for (int i=0; i<newReceivers.size(); i++) {
11490                        ResolveInfo ri = newReceivers.get(i);
11491                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11492                            newReceivers.remove(i);
11493                            i--;
11494                        }
11495                    }
11496                }
11497                if (newReceivers != null && newReceivers.size() == 0) {
11498                    newReceivers = null;
11499                }
11500                if (receivers == null) {
11501                    receivers = newReceivers;
11502                } else if (newReceivers != null) {
11503                    // We need to concatenate the additional receivers
11504                    // found with what we have do far.  This would be easy,
11505                    // but we also need to de-dup any receivers that are
11506                    // singleUser.
11507                    if (!scannedFirstReceivers) {
11508                        // Collect any single user receivers we had already retrieved.
11509                        scannedFirstReceivers = true;
11510                        for (int i=0; i<receivers.size(); i++) {
11511                            ResolveInfo ri = receivers.get(i);
11512                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11513                                ComponentName cn = new ComponentName(
11514                                        ri.activityInfo.packageName, ri.activityInfo.name);
11515                                if (singleUserReceivers == null) {
11516                                    singleUserReceivers = new HashSet<ComponentName>();
11517                                }
11518                                singleUserReceivers.add(cn);
11519                            }
11520                        }
11521                    }
11522                    // Add the new results to the existing results, tracking
11523                    // and de-dupping single user receivers.
11524                    for (int i=0; i<newReceivers.size(); i++) {
11525                        ResolveInfo ri = newReceivers.get(i);
11526                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11527                            ComponentName cn = new ComponentName(
11528                                    ri.activityInfo.packageName, ri.activityInfo.name);
11529                            if (singleUserReceivers == null) {
11530                                singleUserReceivers = new HashSet<ComponentName>();
11531                            }
11532                            if (!singleUserReceivers.contains(cn)) {
11533                                singleUserReceivers.add(cn);
11534                                receivers.add(ri);
11535                            }
11536                        } else {
11537                            receivers.add(ri);
11538                        }
11539                    }
11540                }
11541            }
11542        } catch (RemoteException ex) {
11543            // pm is in same process, this will never happen.
11544        }
11545        return receivers;
11546    }
11547
11548    private final int broadcastIntentLocked(ProcessRecord callerApp,
11549            String callerPackage, Intent intent, String resolvedType,
11550            IIntentReceiver resultTo, int resultCode, String resultData,
11551            Bundle map, String requiredPermission,
11552            boolean ordered, boolean sticky, int callingPid, int callingUid,
11553            int userId) {
11554        intent = new Intent(intent);
11555
11556        // By default broadcasts do not go to stopped apps.
11557        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11558
11559        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11560            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11561            + " ordered=" + ordered + " userid=" + userId);
11562        if ((resultTo != null) && !ordered) {
11563            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11564        }
11565
11566        userId = handleIncomingUser(callingPid, callingUid, userId,
11567                true, false, "broadcast", callerPackage);
11568
11569        // Make sure that the user who is receiving this broadcast is started.
11570        // If not, we will just skip it.
11571        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11572            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11573                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11574                Slog.w(TAG, "Skipping broadcast of " + intent
11575                        + ": user " + userId + " is stopped");
11576                return ActivityManager.BROADCAST_SUCCESS;
11577            }
11578        }
11579
11580        /*
11581         * Prevent non-system code (defined here to be non-persistent
11582         * processes) from sending protected broadcasts.
11583         */
11584        int callingAppId = UserHandle.getAppId(callingUid);
11585        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11586            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11587            callingUid == 0) {
11588            // Always okay.
11589        } else if (callerApp == null || !callerApp.persistent) {
11590            try {
11591                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11592                        intent.getAction())) {
11593                    String msg = "Permission Denial: not allowed to send broadcast "
11594                            + intent.getAction() + " from pid="
11595                            + callingPid + ", uid=" + callingUid;
11596                    Slog.w(TAG, msg);
11597                    throw new SecurityException(msg);
11598                }
11599            } catch (RemoteException e) {
11600                Slog.w(TAG, "Remote exception", e);
11601                return ActivityManager.BROADCAST_SUCCESS;
11602            }
11603        }
11604
11605        // Handle special intents: if this broadcast is from the package
11606        // manager about a package being removed, we need to remove all of
11607        // its activities from the history stack.
11608        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11609                intent.getAction());
11610        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11611                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11612                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11613                || uidRemoved) {
11614            if (checkComponentPermission(
11615                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11616                    callingPid, callingUid, -1, true)
11617                    == PackageManager.PERMISSION_GRANTED) {
11618                if (uidRemoved) {
11619                    final Bundle intentExtras = intent.getExtras();
11620                    final int uid = intentExtras != null
11621                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11622                    if (uid >= 0) {
11623                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11624                        synchronized (bs) {
11625                            bs.removeUidStatsLocked(uid);
11626                        }
11627                    }
11628                } else {
11629                    // If resources are unavailable just force stop all
11630                    // those packages and flush the attribute cache as well.
11631                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11632                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11633                        if (list != null && (list.length > 0)) {
11634                            for (String pkg : list) {
11635                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11636                            }
11637                            sendPackageBroadcastLocked(
11638                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11639                        }
11640                    } else {
11641                        Uri data = intent.getData();
11642                        String ssp;
11643                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11644                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11645                                forceStopPackageLocked(ssp,
11646                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11647                                        false, userId);
11648                            }
11649                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11650                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11651                                        new String[] {ssp}, userId);
11652                            }
11653                        }
11654                    }
11655                }
11656            } else {
11657                String msg = "Permission Denial: " + intent.getAction()
11658                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11659                        + ", uid=" + callingUid + ")"
11660                        + " requires "
11661                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11662                Slog.w(TAG, msg);
11663                throw new SecurityException(msg);
11664            }
11665
11666        // Special case for adding a package: by default turn on compatibility
11667        // mode.
11668        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11669            Uri data = intent.getData();
11670            String ssp;
11671            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11672                mCompatModePackages.handlePackageAddedLocked(ssp,
11673                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11674            }
11675        }
11676
11677        /*
11678         * If this is the time zone changed action, queue up a message that will reset the timezone
11679         * of all currently running processes. This message will get queued up before the broadcast
11680         * happens.
11681         */
11682        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11683            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11684        }
11685
11686        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11687            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11688        }
11689
11690        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11691            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11692            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11693        }
11694
11695        // Add to the sticky list if requested.
11696        if (sticky) {
11697            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11698                    callingPid, callingUid)
11699                    != PackageManager.PERMISSION_GRANTED) {
11700                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11701                        + callingPid + ", uid=" + callingUid
11702                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11703                Slog.w(TAG, msg);
11704                throw new SecurityException(msg);
11705            }
11706            if (requiredPermission != null) {
11707                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11708                        + " and enforce permission " + requiredPermission);
11709                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11710            }
11711            if (intent.getComponent() != null) {
11712                throw new SecurityException(
11713                        "Sticky broadcasts can't target a specific component");
11714            }
11715            // We use userId directly here, since the "all" target is maintained
11716            // as a separate set of sticky broadcasts.
11717            if (userId != UserHandle.USER_ALL) {
11718                // But first, if this is not a broadcast to all users, then
11719                // make sure it doesn't conflict with an existing broadcast to
11720                // all users.
11721                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11722                        UserHandle.USER_ALL);
11723                if (stickies != null) {
11724                    ArrayList<Intent> list = stickies.get(intent.getAction());
11725                    if (list != null) {
11726                        int N = list.size();
11727                        int i;
11728                        for (i=0; i<N; i++) {
11729                            if (intent.filterEquals(list.get(i))) {
11730                                throw new IllegalArgumentException(
11731                                        "Sticky broadcast " + intent + " for user "
11732                                        + userId + " conflicts with existing global broadcast");
11733                            }
11734                        }
11735                    }
11736                }
11737            }
11738            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11739            if (stickies == null) {
11740                stickies = new HashMap<String, ArrayList<Intent>>();
11741                mStickyBroadcasts.put(userId, stickies);
11742            }
11743            ArrayList<Intent> list = stickies.get(intent.getAction());
11744            if (list == null) {
11745                list = new ArrayList<Intent>();
11746                stickies.put(intent.getAction(), list);
11747            }
11748            int N = list.size();
11749            int i;
11750            for (i=0; i<N; i++) {
11751                if (intent.filterEquals(list.get(i))) {
11752                    // This sticky already exists, replace it.
11753                    list.set(i, new Intent(intent));
11754                    break;
11755                }
11756            }
11757            if (i >= N) {
11758                list.add(new Intent(intent));
11759            }
11760        }
11761
11762        int[] users;
11763        if (userId == UserHandle.USER_ALL) {
11764            // Caller wants broadcast to go to all started users.
11765            users = mStartedUserArray;
11766        } else {
11767            // Caller wants broadcast to go to one specific user.
11768            users = new int[] {userId};
11769        }
11770
11771        // Figure out who all will receive this broadcast.
11772        List receivers = null;
11773        List<BroadcastFilter> registeredReceivers = null;
11774        // Need to resolve the intent to interested receivers...
11775        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11776                 == 0) {
11777            receivers = collectReceiverComponents(intent, resolvedType, users);
11778        }
11779        if (intent.getComponent() == null) {
11780            registeredReceivers = mReceiverResolver.queryIntent(intent,
11781                    resolvedType, false, userId);
11782        }
11783
11784        final boolean replacePending =
11785                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11786
11787        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11788                + " replacePending=" + replacePending);
11789
11790        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11791        if (!ordered && NR > 0) {
11792            // If we are not serializing this broadcast, then send the
11793            // registered receivers separately so they don't wait for the
11794            // components to be launched.
11795            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11796            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11797                    callerPackage, callingPid, callingUid, requiredPermission,
11798                    registeredReceivers, resultTo, resultCode, resultData, map,
11799                    ordered, sticky, false, userId);
11800            if (DEBUG_BROADCAST) Slog.v(
11801                    TAG, "Enqueueing parallel broadcast " + r);
11802            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11803            if (!replaced) {
11804                queue.enqueueParallelBroadcastLocked(r);
11805                queue.scheduleBroadcastsLocked();
11806            }
11807            registeredReceivers = null;
11808            NR = 0;
11809        }
11810
11811        // Merge into one list.
11812        int ir = 0;
11813        if (receivers != null) {
11814            // A special case for PACKAGE_ADDED: do not allow the package
11815            // being added to see this broadcast.  This prevents them from
11816            // using this as a back door to get run as soon as they are
11817            // installed.  Maybe in the future we want to have a special install
11818            // broadcast or such for apps, but we'd like to deliberately make
11819            // this decision.
11820            String skipPackages[] = null;
11821            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11822                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11823                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11824                Uri data = intent.getData();
11825                if (data != null) {
11826                    String pkgName = data.getSchemeSpecificPart();
11827                    if (pkgName != null) {
11828                        skipPackages = new String[] { pkgName };
11829                    }
11830                }
11831            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11832                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11833            }
11834            if (skipPackages != null && (skipPackages.length > 0)) {
11835                for (String skipPackage : skipPackages) {
11836                    if (skipPackage != null) {
11837                        int NT = receivers.size();
11838                        for (int it=0; it<NT; it++) {
11839                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11840                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11841                                receivers.remove(it);
11842                                it--;
11843                                NT--;
11844                            }
11845                        }
11846                    }
11847                }
11848            }
11849
11850            int NT = receivers != null ? receivers.size() : 0;
11851            int it = 0;
11852            ResolveInfo curt = null;
11853            BroadcastFilter curr = null;
11854            while (it < NT && ir < NR) {
11855                if (curt == null) {
11856                    curt = (ResolveInfo)receivers.get(it);
11857                }
11858                if (curr == null) {
11859                    curr = registeredReceivers.get(ir);
11860                }
11861                if (curr.getPriority() >= curt.priority) {
11862                    // Insert this broadcast record into the final list.
11863                    receivers.add(it, curr);
11864                    ir++;
11865                    curr = null;
11866                    it++;
11867                    NT++;
11868                } else {
11869                    // Skip to the next ResolveInfo in the final list.
11870                    it++;
11871                    curt = null;
11872                }
11873            }
11874        }
11875        while (ir < NR) {
11876            if (receivers == null) {
11877                receivers = new ArrayList();
11878            }
11879            receivers.add(registeredReceivers.get(ir));
11880            ir++;
11881        }
11882
11883        if ((receivers != null && receivers.size() > 0)
11884                || resultTo != null) {
11885            BroadcastQueue queue = broadcastQueueForIntent(intent);
11886            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11887                    callerPackage, callingPid, callingUid, requiredPermission,
11888                    receivers, resultTo, resultCode, resultData, map, ordered,
11889                    sticky, false, userId);
11890            if (DEBUG_BROADCAST) Slog.v(
11891                    TAG, "Enqueueing ordered broadcast " + r
11892                    + ": prev had " + queue.mOrderedBroadcasts.size());
11893            if (DEBUG_BROADCAST) {
11894                int seq = r.intent.getIntExtra("seq", -1);
11895                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11896            }
11897            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11898            if (!replaced) {
11899                queue.enqueueOrderedBroadcastLocked(r);
11900                queue.scheduleBroadcastsLocked();
11901            }
11902        }
11903
11904        return ActivityManager.BROADCAST_SUCCESS;
11905    }
11906
11907    final Intent verifyBroadcastLocked(Intent intent) {
11908        // Refuse possible leaked file descriptors
11909        if (intent != null && intent.hasFileDescriptors() == true) {
11910            throw new IllegalArgumentException("File descriptors passed in Intent");
11911        }
11912
11913        int flags = intent.getFlags();
11914
11915        if (!mProcessesReady) {
11916            // if the caller really truly claims to know what they're doing, go
11917            // ahead and allow the broadcast without launching any receivers
11918            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11919                intent = new Intent(intent);
11920                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11921            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11922                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11923                        + " before boot completion");
11924                throw new IllegalStateException("Cannot broadcast before boot completed");
11925            }
11926        }
11927
11928        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11929            throw new IllegalArgumentException(
11930                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11931        }
11932
11933        return intent;
11934    }
11935
11936    public final int broadcastIntent(IApplicationThread caller,
11937            Intent intent, String resolvedType, IIntentReceiver resultTo,
11938            int resultCode, String resultData, Bundle map,
11939            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11940        enforceNotIsolatedCaller("broadcastIntent");
11941        synchronized(this) {
11942            intent = verifyBroadcastLocked(intent);
11943
11944            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11945            final int callingPid = Binder.getCallingPid();
11946            final int callingUid = Binder.getCallingUid();
11947            final long origId = Binder.clearCallingIdentity();
11948            int res = broadcastIntentLocked(callerApp,
11949                    callerApp != null ? callerApp.info.packageName : null,
11950                    intent, resolvedType, resultTo,
11951                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11952                    callingPid, callingUid, userId);
11953            Binder.restoreCallingIdentity(origId);
11954            return res;
11955        }
11956    }
11957
11958    int broadcastIntentInPackage(String packageName, int uid,
11959            Intent intent, String resolvedType, IIntentReceiver resultTo,
11960            int resultCode, String resultData, Bundle map,
11961            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11962        synchronized(this) {
11963            intent = verifyBroadcastLocked(intent);
11964
11965            final long origId = Binder.clearCallingIdentity();
11966            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11967                    resultTo, resultCode, resultData, map, requiredPermission,
11968                    serialized, sticky, -1, uid, userId);
11969            Binder.restoreCallingIdentity(origId);
11970            return res;
11971        }
11972    }
11973
11974    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11975        // Refuse possible leaked file descriptors
11976        if (intent != null && intent.hasFileDescriptors() == true) {
11977            throw new IllegalArgumentException("File descriptors passed in Intent");
11978        }
11979
11980        userId = handleIncomingUser(Binder.getCallingPid(),
11981                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11982
11983        synchronized(this) {
11984            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11985                    != PackageManager.PERMISSION_GRANTED) {
11986                String msg = "Permission Denial: unbroadcastIntent() from pid="
11987                        + Binder.getCallingPid()
11988                        + ", uid=" + Binder.getCallingUid()
11989                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11990                Slog.w(TAG, msg);
11991                throw new SecurityException(msg);
11992            }
11993            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11994            if (stickies != null) {
11995                ArrayList<Intent> list = stickies.get(intent.getAction());
11996                if (list != null) {
11997                    int N = list.size();
11998                    int i;
11999                    for (i=0; i<N; i++) {
12000                        if (intent.filterEquals(list.get(i))) {
12001                            list.remove(i);
12002                            break;
12003                        }
12004                    }
12005                    if (list.size() <= 0) {
12006                        stickies.remove(intent.getAction());
12007                    }
12008                }
12009                if (stickies.size() <= 0) {
12010                    mStickyBroadcasts.remove(userId);
12011                }
12012            }
12013        }
12014    }
12015
12016    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12017            String resultData, Bundle resultExtras, boolean resultAbort,
12018            boolean explicit) {
12019        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12020        if (r == null) {
12021            Slog.w(TAG, "finishReceiver called but not found on queue");
12022            return false;
12023        }
12024
12025        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12026                explicit);
12027    }
12028
12029    public void finishReceiver(IBinder who, int resultCode, String resultData,
12030            Bundle resultExtras, boolean resultAbort) {
12031        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12032
12033        // Refuse possible leaked file descriptors
12034        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12035            throw new IllegalArgumentException("File descriptors passed in Bundle");
12036        }
12037
12038        final long origId = Binder.clearCallingIdentity();
12039        try {
12040            boolean doNext = false;
12041            BroadcastRecord r = null;
12042
12043            synchronized(this) {
12044                r = broadcastRecordForReceiverLocked(who);
12045                if (r != null) {
12046                    doNext = r.queue.finishReceiverLocked(r, resultCode,
12047                        resultData, resultExtras, resultAbort, true);
12048                }
12049            }
12050
12051            if (doNext) {
12052                r.queue.processNextBroadcast(false);
12053            }
12054            trimApplications();
12055        } finally {
12056            Binder.restoreCallingIdentity(origId);
12057        }
12058    }
12059
12060    // =========================================================
12061    // INSTRUMENTATION
12062    // =========================================================
12063
12064    public boolean startInstrumentation(ComponentName className,
12065            String profileFile, int flags, Bundle arguments,
12066            IInstrumentationWatcher watcher, int userId) {
12067        enforceNotIsolatedCaller("startInstrumentation");
12068        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12069                userId, false, true, "startInstrumentation", null);
12070        // Refuse possible leaked file descriptors
12071        if (arguments != null && arguments.hasFileDescriptors()) {
12072            throw new IllegalArgumentException("File descriptors passed in Bundle");
12073        }
12074
12075        synchronized(this) {
12076            InstrumentationInfo ii = null;
12077            ApplicationInfo ai = null;
12078            try {
12079                ii = mContext.getPackageManager().getInstrumentationInfo(
12080                    className, STOCK_PM_FLAGS);
12081                ai = AppGlobals.getPackageManager().getApplicationInfo(
12082                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12083            } catch (PackageManager.NameNotFoundException e) {
12084            } catch (RemoteException e) {
12085            }
12086            if (ii == null) {
12087                reportStartInstrumentationFailure(watcher, className,
12088                        "Unable to find instrumentation info for: " + className);
12089                return false;
12090            }
12091            if (ai == null) {
12092                reportStartInstrumentationFailure(watcher, className,
12093                        "Unable to find instrumentation target package: " + ii.targetPackage);
12094                return false;
12095            }
12096
12097            int match = mContext.getPackageManager().checkSignatures(
12098                    ii.targetPackage, ii.packageName);
12099            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12100                String msg = "Permission Denial: starting instrumentation "
12101                        + className + " from pid="
12102                        + Binder.getCallingPid()
12103                        + ", uid=" + Binder.getCallingPid()
12104                        + " not allowed because package " + ii.packageName
12105                        + " does not have a signature matching the target "
12106                        + ii.targetPackage;
12107                reportStartInstrumentationFailure(watcher, className, msg);
12108                throw new SecurityException(msg);
12109            }
12110
12111            final long origId = Binder.clearCallingIdentity();
12112            // Instrumentation can kill and relaunch even persistent processes
12113            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12114            ProcessRecord app = addAppLocked(ai, false);
12115            app.instrumentationClass = className;
12116            app.instrumentationInfo = ai;
12117            app.instrumentationProfileFile = profileFile;
12118            app.instrumentationArguments = arguments;
12119            app.instrumentationWatcher = watcher;
12120            app.instrumentationResultClass = className;
12121            Binder.restoreCallingIdentity(origId);
12122        }
12123
12124        return true;
12125    }
12126
12127    /**
12128     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12129     * error to the logs, but if somebody is watching, send the report there too.  This enables
12130     * the "am" command to report errors with more information.
12131     *
12132     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12133     * @param cn The component name of the instrumentation.
12134     * @param report The error report.
12135     */
12136    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12137            ComponentName cn, String report) {
12138        Slog.w(TAG, report);
12139        try {
12140            if (watcher != null) {
12141                Bundle results = new Bundle();
12142                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12143                results.putString("Error", report);
12144                watcher.instrumentationStatus(cn, -1, results);
12145            }
12146        } catch (RemoteException e) {
12147            Slog.w(TAG, e);
12148        }
12149    }
12150
12151    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12152        if (app.instrumentationWatcher != null) {
12153            try {
12154                // NOTE:  IInstrumentationWatcher *must* be oneway here
12155                app.instrumentationWatcher.instrumentationFinished(
12156                    app.instrumentationClass,
12157                    resultCode,
12158                    results);
12159            } catch (RemoteException e) {
12160            }
12161        }
12162        app.instrumentationWatcher = null;
12163        app.instrumentationClass = null;
12164        app.instrumentationInfo = null;
12165        app.instrumentationProfileFile = null;
12166        app.instrumentationArguments = null;
12167
12168        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12169    }
12170
12171    public void finishInstrumentation(IApplicationThread target,
12172            int resultCode, Bundle results) {
12173        int userId = UserHandle.getCallingUserId();
12174        // Refuse possible leaked file descriptors
12175        if (results != null && results.hasFileDescriptors()) {
12176            throw new IllegalArgumentException("File descriptors passed in Intent");
12177        }
12178
12179        synchronized(this) {
12180            ProcessRecord app = getRecordForAppLocked(target);
12181            if (app == null) {
12182                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12183                return;
12184            }
12185            final long origId = Binder.clearCallingIdentity();
12186            finishInstrumentationLocked(app, resultCode, results);
12187            Binder.restoreCallingIdentity(origId);
12188        }
12189    }
12190
12191    // =========================================================
12192    // CONFIGURATION
12193    // =========================================================
12194
12195    public ConfigurationInfo getDeviceConfigurationInfo() {
12196        ConfigurationInfo config = new ConfigurationInfo();
12197        synchronized (this) {
12198            config.reqTouchScreen = mConfiguration.touchscreen;
12199            config.reqKeyboardType = mConfiguration.keyboard;
12200            config.reqNavigation = mConfiguration.navigation;
12201            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12202                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12203                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12204            }
12205            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12206                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12207                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12208            }
12209            config.reqGlEsVersion = GL_ES_VERSION;
12210        }
12211        return config;
12212    }
12213
12214    public Configuration getConfiguration() {
12215        Configuration ci;
12216        synchronized(this) {
12217            ci = new Configuration(mConfiguration);
12218        }
12219        return ci;
12220    }
12221
12222    public void updatePersistentConfiguration(Configuration values) {
12223        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12224                "updateConfiguration()");
12225        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12226                "updateConfiguration()");
12227        if (values == null) {
12228            throw new NullPointerException("Configuration must not be null");
12229        }
12230
12231        synchronized(this) {
12232            final long origId = Binder.clearCallingIdentity();
12233            updateConfigurationLocked(values, null, true, false);
12234            Binder.restoreCallingIdentity(origId);
12235        }
12236    }
12237
12238    public void updateConfiguration(Configuration values) {
12239        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12240                "updateConfiguration()");
12241
12242        synchronized(this) {
12243            if (values == null && mWindowManager != null) {
12244                // sentinel: fetch the current configuration from the window manager
12245                values = mWindowManager.computeNewConfiguration();
12246            }
12247
12248            if (mWindowManager != null) {
12249                mProcessList.applyDisplaySize(mWindowManager);
12250            }
12251
12252            final long origId = Binder.clearCallingIdentity();
12253            if (values != null) {
12254                Settings.System.clearConfiguration(values);
12255            }
12256            updateConfigurationLocked(values, null, false, false);
12257            Binder.restoreCallingIdentity(origId);
12258        }
12259    }
12260
12261    /**
12262     * Do either or both things: (1) change the current configuration, and (2)
12263     * make sure the given activity is running with the (now) current
12264     * configuration.  Returns true if the activity has been left running, or
12265     * false if <var>starting</var> is being destroyed to match the new
12266     * configuration.
12267     * @param persistent TODO
12268     */
12269    boolean updateConfigurationLocked(Configuration values,
12270            ActivityRecord starting, boolean persistent, boolean initLocale) {
12271        // do nothing if we are headless
12272        if (mHeadless) return true;
12273
12274        int changes = 0;
12275
12276        boolean kept = true;
12277
12278        if (values != null) {
12279            Configuration newConfig = new Configuration(mConfiguration);
12280            changes = newConfig.updateFrom(values);
12281            if (changes != 0) {
12282                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12283                    Slog.i(TAG, "Updating configuration to: " + values);
12284                }
12285
12286                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12287
12288                if (values.locale != null && !initLocale) {
12289                    saveLocaleLocked(values.locale,
12290                                     !values.locale.equals(mConfiguration.locale),
12291                                     values.userSetLocale);
12292                }
12293
12294                mConfigurationSeq++;
12295                if (mConfigurationSeq <= 0) {
12296                    mConfigurationSeq = 1;
12297                }
12298                newConfig.seq = mConfigurationSeq;
12299                mConfiguration = newConfig;
12300                Slog.i(TAG, "Config changed: " + newConfig);
12301
12302                final Configuration configCopy = new Configuration(mConfiguration);
12303
12304                // TODO: If our config changes, should we auto dismiss any currently
12305                // showing dialogs?
12306                mShowDialogs = shouldShowDialogs(newConfig);
12307
12308                AttributeCache ac = AttributeCache.instance();
12309                if (ac != null) {
12310                    ac.updateConfiguration(configCopy);
12311                }
12312
12313                // Make sure all resources in our process are updated
12314                // right now, so that anyone who is going to retrieve
12315                // resource values after we return will be sure to get
12316                // the new ones.  This is especially important during
12317                // boot, where the first config change needs to guarantee
12318                // all resources have that config before following boot
12319                // code is executed.
12320                mSystemThread.applyConfigurationToResources(configCopy);
12321
12322                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12323                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12324                    msg.obj = new Configuration(configCopy);
12325                    mHandler.sendMessage(msg);
12326                }
12327
12328                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12329                    ProcessRecord app = mLruProcesses.get(i);
12330                    try {
12331                        if (app.thread != null) {
12332                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12333                                    + app.processName + " new config " + mConfiguration);
12334                            app.thread.scheduleConfigurationChanged(configCopy);
12335                        }
12336                    } catch (Exception e) {
12337                    }
12338                }
12339                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12340                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12341                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12342                        | Intent.FLAG_RECEIVER_FOREGROUND);
12343                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12344                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12345                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12346                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12347                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12348                    broadcastIntentLocked(null, null, intent,
12349                            null, null, 0, null, null,
12350                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12351                }
12352            }
12353        }
12354
12355        if (changes != 0 && starting == null) {
12356            // If the configuration changed, and the caller is not already
12357            // in the process of starting an activity, then find the top
12358            // activity to check if its configuration needs to change.
12359            starting = mMainStack.topRunningActivityLocked(null);
12360        }
12361
12362        if (starting != null) {
12363            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12364            // And we need to make sure at this point that all other activities
12365            // are made visible with the correct configuration.
12366            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12367        }
12368
12369        if (values != null && mWindowManager != null) {
12370            mWindowManager.setNewConfiguration(mConfiguration);
12371        }
12372
12373        return kept;
12374    }
12375
12376    /**
12377     * Decide based on the configuration whether we should shouw the ANR,
12378     * crash, etc dialogs.  The idea is that if there is no affordnace to
12379     * press the on-screen buttons, we shouldn't show the dialog.
12380     *
12381     * A thought: SystemUI might also want to get told about this, the Power
12382     * dialog / global actions also might want different behaviors.
12383     */
12384    private static final boolean shouldShowDialogs(Configuration config) {
12385        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12386                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12387    }
12388
12389    /**
12390     * Save the locale.  You must be inside a synchronized (this) block.
12391     */
12392    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12393        if(isDiff) {
12394            SystemProperties.set("user.language", l.getLanguage());
12395            SystemProperties.set("user.region", l.getCountry());
12396        }
12397
12398        if(isPersist) {
12399            SystemProperties.set("persist.sys.language", l.getLanguage());
12400            SystemProperties.set("persist.sys.country", l.getCountry());
12401            SystemProperties.set("persist.sys.localevar", l.getVariant());
12402        }
12403    }
12404
12405    @Override
12406    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12407        ActivityRecord srec = ActivityRecord.forToken(token);
12408        return srec != null && srec.task.affinity != null &&
12409                srec.task.affinity.equals(destAffinity);
12410    }
12411
12412    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12413            Intent resultData) {
12414        ComponentName dest = destIntent.getComponent();
12415
12416        synchronized (this) {
12417            ActivityRecord srec = ActivityRecord.forToken(token);
12418            if (srec == null) {
12419                return false;
12420            }
12421            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12422            final int start = history.indexOf(srec);
12423            if (start < 0) {
12424                // Current activity is not in history stack; do nothing.
12425                return false;
12426            }
12427            int finishTo = start - 1;
12428            ActivityRecord parent = null;
12429            boolean foundParentInTask = false;
12430            if (dest != null) {
12431                TaskRecord tr = srec.task;
12432                for (int i = start - 1; i >= 0; i--) {
12433                    ActivityRecord r = history.get(i);
12434                    if (tr != r.task) {
12435                        // Couldn't find parent in the same task; stop at the one above this.
12436                        // (Root of current task; in-app "home" behavior)
12437                        // Always at least finish the current activity.
12438                        finishTo = Math.min(start - 1, i + 1);
12439                        parent = history.get(finishTo);
12440                        break;
12441                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12442                            r.info.name.equals(dest.getClassName())) {
12443                        finishTo = i;
12444                        parent = r;
12445                        foundParentInTask = true;
12446                        break;
12447                    }
12448                }
12449            }
12450
12451            if (mController != null) {
12452                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12453                if (next != null) {
12454                    // ask watcher if this is allowed
12455                    boolean resumeOK = true;
12456                    try {
12457                        resumeOK = mController.activityResuming(next.packageName);
12458                    } catch (RemoteException e) {
12459                        mController = null;
12460                    }
12461
12462                    if (!resumeOK) {
12463                        return false;
12464                    }
12465                }
12466            }
12467            final long origId = Binder.clearCallingIdentity();
12468            for (int i = start; i > finishTo; i--) {
12469                ActivityRecord r = history.get(i);
12470                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12471                        "navigate-up", true);
12472                // Only return the supplied result for the first activity finished
12473                resultCode = Activity.RESULT_CANCELED;
12474                resultData = null;
12475            }
12476
12477            if (parent != null && foundParentInTask) {
12478                final int parentLaunchMode = parent.info.launchMode;
12479                final int destIntentFlags = destIntent.getFlags();
12480                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12481                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12482                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12483                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12484                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12485                } else {
12486                    try {
12487                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12488                                destIntent.getComponent(), 0, srec.userId);
12489                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12490                                null, aInfo, parent.appToken, null,
12491                                0, -1, parent.launchedFromUid, 0, null, true, null);
12492                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12493                    } catch (RemoteException e) {
12494                        foundParentInTask = false;
12495                    }
12496                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12497                            resultData, "navigate-up", true);
12498                }
12499            }
12500            Binder.restoreCallingIdentity(origId);
12501            return foundParentInTask;
12502        }
12503    }
12504
12505    public int getLaunchedFromUid(IBinder activityToken) {
12506        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12507        if (srec == null) {
12508            return -1;
12509        }
12510        return srec.launchedFromUid;
12511    }
12512
12513    // =========================================================
12514    // LIFETIME MANAGEMENT
12515    // =========================================================
12516
12517    // Returns which broadcast queue the app is the current [or imminent] receiver
12518    // on, or 'null' if the app is not an active broadcast recipient.
12519    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12520        BroadcastRecord r = app.curReceiver;
12521        if (r != null) {
12522            return r.queue;
12523        }
12524
12525        // It's not the current receiver, but it might be starting up to become one
12526        synchronized (this) {
12527            for (BroadcastQueue queue : mBroadcastQueues) {
12528                r = queue.mPendingBroadcast;
12529                if (r != null && r.curApp == app) {
12530                    // found it; report which queue it's in
12531                    return queue;
12532                }
12533            }
12534        }
12535
12536        return null;
12537    }
12538
12539    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12540            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12541        if (mAdjSeq == app.adjSeq) {
12542            // This adjustment has already been computed.  If we are calling
12543            // from the top, we may have already computed our adjustment with
12544            // an earlier hidden adjustment that isn't really for us... if
12545            // so, use the new hidden adjustment.
12546            if (!recursed && app.hidden) {
12547                if (app.hasActivities) {
12548                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12549                } else if (app.hasClientActivities) {
12550                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12551                } else {
12552                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12553                }
12554            }
12555            return app.curRawAdj;
12556        }
12557
12558        if (app.thread == null) {
12559            app.adjSeq = mAdjSeq;
12560            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12561            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12562        }
12563
12564        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12565        app.adjSource = null;
12566        app.adjTarget = null;
12567        app.empty = false;
12568        app.hidden = false;
12569        app.hasClientActivities = false;
12570
12571        final int activitiesSize = app.activities.size();
12572
12573        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12574            // The max adjustment doesn't allow this app to be anything
12575            // below foreground, so it is not worth doing work for it.
12576            app.adjType = "fixed";
12577            app.adjSeq = mAdjSeq;
12578            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12579            app.hasActivities = false;
12580            app.foregroundActivities = false;
12581            app.keeping = true;
12582            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12583            // System process can do UI, and when they do we want to have
12584            // them trim their memory after the user leaves the UI.  To
12585            // facilitate this, here we need to determine whether or not it
12586            // is currently showing UI.
12587            app.systemNoUi = true;
12588            if (app == TOP_APP) {
12589                app.systemNoUi = false;
12590                app.hasActivities = true;
12591            } else if (activitiesSize > 0) {
12592                for (int j = 0; j < activitiesSize; j++) {
12593                    final ActivityRecord r = app.activities.get(j);
12594                    if (r.visible) {
12595                        app.systemNoUi = false;
12596                    }
12597                    if (r.app == app) {
12598                        app.hasActivities = true;
12599                    }
12600                }
12601            }
12602            return (app.curAdj=app.maxAdj);
12603        }
12604
12605        app.keeping = false;
12606        app.systemNoUi = false;
12607        app.hasActivities = false;
12608
12609        // Determine the importance of the process, starting with most
12610        // important to least, and assign an appropriate OOM adjustment.
12611        int adj;
12612        int schedGroup;
12613        boolean foregroundActivities = false;
12614        boolean interesting = false;
12615        BroadcastQueue queue;
12616        if (app == TOP_APP) {
12617            // The last app on the list is the foreground app.
12618            adj = ProcessList.FOREGROUND_APP_ADJ;
12619            schedGroup = Process.THREAD_GROUP_DEFAULT;
12620            app.adjType = "top-activity";
12621            foregroundActivities = true;
12622            interesting = true;
12623            app.hasActivities = true;
12624        } else if (app.instrumentationClass != null) {
12625            // Don't want to kill running instrumentation.
12626            adj = ProcessList.FOREGROUND_APP_ADJ;
12627            schedGroup = Process.THREAD_GROUP_DEFAULT;
12628            app.adjType = "instrumentation";
12629            interesting = true;
12630        } else if ((queue = isReceivingBroadcast(app)) != null) {
12631            // An app that is currently receiving a broadcast also
12632            // counts as being in the foreground for OOM killer purposes.
12633            // It's placed in a sched group based on the nature of the
12634            // broadcast as reflected by which queue it's active in.
12635            adj = ProcessList.FOREGROUND_APP_ADJ;
12636            schedGroup = (queue == mFgBroadcastQueue)
12637                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12638            app.adjType = "broadcast";
12639        } else if (app.executingServices.size() > 0) {
12640            // An app that is currently executing a service callback also
12641            // counts as being in the foreground.
12642            adj = ProcessList.FOREGROUND_APP_ADJ;
12643            schedGroup = Process.THREAD_GROUP_DEFAULT;
12644            app.adjType = "exec-service";
12645        } else {
12646            // Assume process is hidden (has activities); we will correct
12647            // later if this is not the case.
12648            adj = hiddenAdj;
12649            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12650            app.hidden = true;
12651            app.adjType = "bg-act";
12652        }
12653
12654        boolean hasStoppingActivities = false;
12655
12656        // Examine all activities if not already foreground.
12657        if (!foregroundActivities && activitiesSize > 0) {
12658            for (int j = 0; j < activitiesSize; j++) {
12659                final ActivityRecord r = app.activities.get(j);
12660                if (r.visible) {
12661                    // App has a visible activity; only upgrade adjustment.
12662                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12663                        adj = ProcessList.VISIBLE_APP_ADJ;
12664                        app.adjType = "visible";
12665                    }
12666                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12667                    app.hidden = false;
12668                    app.hasActivities = true;
12669                    foregroundActivities = true;
12670                    break;
12671                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12672                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12673                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12674                        app.adjType = "pausing";
12675                    }
12676                    app.hidden = false;
12677                    foregroundActivities = true;
12678                } else if (r.state == ActivityState.STOPPING) {
12679                    // We will apply the actual adjustment later, because
12680                    // we want to allow this process to immediately go through
12681                    // any memory trimming that is in effect.
12682                    app.hidden = false;
12683                    foregroundActivities = true;
12684                    hasStoppingActivities = true;
12685                }
12686                if (r.app == app) {
12687                    app.hasActivities = true;
12688                }
12689            }
12690        }
12691
12692        if (adj == hiddenAdj && !app.hasActivities) {
12693            if (app.hasClientActivities) {
12694                adj = clientHiddenAdj;
12695                app.adjType = "bg-client-act";
12696            } else {
12697                // Whoops, this process is completely empty as far as we know
12698                // at this point.
12699                adj = emptyAdj;
12700                app.empty = true;
12701                app.adjType = "bg-empty";
12702            }
12703        }
12704
12705        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12706            if (app.foregroundServices) {
12707                // The user is aware of this app, so make it visible.
12708                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12709                app.hidden = false;
12710                app.adjType = "fg-service";
12711                schedGroup = Process.THREAD_GROUP_DEFAULT;
12712            } else if (app.forcingToForeground != null) {
12713                // The user is aware of this app, so make it visible.
12714                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12715                app.hidden = false;
12716                app.adjType = "force-fg";
12717                app.adjSource = app.forcingToForeground;
12718                schedGroup = Process.THREAD_GROUP_DEFAULT;
12719            }
12720        }
12721
12722        if (app.foregroundServices) {
12723            interesting = true;
12724        }
12725
12726        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12727            // We don't want to kill the current heavy-weight process.
12728            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12729            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12730            app.hidden = false;
12731            app.adjType = "heavy";
12732        }
12733
12734        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12735            // This process is hosting what we currently consider to be the
12736            // home app, so we don't want to let it go into the background.
12737            adj = ProcessList.HOME_APP_ADJ;
12738            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12739            app.hidden = false;
12740            app.adjType = "home";
12741        }
12742
12743        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12744                && app.activities.size() > 0) {
12745            // This was the previous process that showed UI to the user.
12746            // We want to try to keep it around more aggressively, to give
12747            // a good experience around switching between two apps.
12748            adj = ProcessList.PREVIOUS_APP_ADJ;
12749            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12750            app.hidden = false;
12751            app.adjType = "previous";
12752        }
12753
12754        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12755                + " reason=" + app.adjType);
12756
12757        // By default, we use the computed adjustment.  It may be changed if
12758        // there are applications dependent on our services or providers, but
12759        // this gives us a baseline and makes sure we don't get into an
12760        // infinite recursion.
12761        app.adjSeq = mAdjSeq;
12762        app.curRawAdj = app.nonStoppingAdj = adj;
12763
12764        if (mBackupTarget != null && app == mBackupTarget.app) {
12765            // If possible we want to avoid killing apps while they're being backed up
12766            if (adj > ProcessList.BACKUP_APP_ADJ) {
12767                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12768                adj = ProcessList.BACKUP_APP_ADJ;
12769                app.adjType = "backup";
12770                app.hidden = false;
12771            }
12772        }
12773
12774        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12775                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12776            final long now = SystemClock.uptimeMillis();
12777            // This process is more important if the top activity is
12778            // bound to the service.
12779            Iterator<ServiceRecord> jt = app.services.iterator();
12780            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12781                ServiceRecord s = jt.next();
12782                if (s.startRequested) {
12783                    if (app.hasShownUi && app != mHomeProcess) {
12784                        // If this process has shown some UI, let it immediately
12785                        // go to the LRU list because it may be pretty heavy with
12786                        // UI stuff.  We'll tag it with a label just to help
12787                        // debug and understand what is going on.
12788                        if (adj > ProcessList.SERVICE_ADJ) {
12789                            app.adjType = "started-bg-ui-services";
12790                        }
12791                    } else {
12792                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12793                            // This service has seen some activity within
12794                            // recent memory, so we will keep its process ahead
12795                            // of the background processes.
12796                            if (adj > ProcessList.SERVICE_ADJ) {
12797                                adj = ProcessList.SERVICE_ADJ;
12798                                app.adjType = "started-services";
12799                                app.hidden = false;
12800                            }
12801                        }
12802                        // If we have let the service slide into the background
12803                        // state, still have some text describing what it is doing
12804                        // even though the service no longer has an impact.
12805                        if (adj > ProcessList.SERVICE_ADJ) {
12806                            app.adjType = "started-bg-services";
12807                        }
12808                    }
12809                    // Don't kill this process because it is doing work; it
12810                    // has said it is doing work.
12811                    app.keeping = true;
12812                }
12813                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12814                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12815                    Iterator<ArrayList<ConnectionRecord>> kt
12816                            = s.connections.values().iterator();
12817                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12818                        ArrayList<ConnectionRecord> clist = kt.next();
12819                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12820                            // XXX should compute this based on the max of
12821                            // all connected clients.
12822                            ConnectionRecord cr = clist.get(i);
12823                            if (cr.binding.client == app) {
12824                                // Binding to ourself is not interesting.
12825                                continue;
12826                            }
12827                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12828                                ProcessRecord client = cr.binding.client;
12829                                int clientAdj = adj;
12830                                int myHiddenAdj = hiddenAdj;
12831                                if (myHiddenAdj > client.hiddenAdj) {
12832                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12833                                        myHiddenAdj = client.hiddenAdj;
12834                                    } else {
12835                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12836                                    }
12837                                }
12838                                int myClientHiddenAdj = clientHiddenAdj;
12839                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12840                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12841                                        myClientHiddenAdj = client.clientHiddenAdj;
12842                                    } else {
12843                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12844                                    }
12845                                }
12846                                int myEmptyAdj = emptyAdj;
12847                                if (myEmptyAdj > client.emptyAdj) {
12848                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12849                                        myEmptyAdj = client.emptyAdj;
12850                                    } else {
12851                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12852                                    }
12853                                }
12854                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12855                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12856                                String adjType = null;
12857                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12858                                    // Not doing bind OOM management, so treat
12859                                    // this guy more like a started service.
12860                                    if (app.hasShownUi && app != mHomeProcess) {
12861                                        // If this process has shown some UI, let it immediately
12862                                        // go to the LRU list because it may be pretty heavy with
12863                                        // UI stuff.  We'll tag it with a label just to help
12864                                        // debug and understand what is going on.
12865                                        if (adj > clientAdj) {
12866                                            adjType = "bound-bg-ui-services";
12867                                        }
12868                                        app.hidden = false;
12869                                        clientAdj = adj;
12870                                    } else {
12871                                        if (now >= (s.lastActivity
12872                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12873                                            // This service has not seen activity within
12874                                            // recent memory, so allow it to drop to the
12875                                            // LRU list if there is no other reason to keep
12876                                            // it around.  We'll also tag it with a label just
12877                                            // to help debug and undertand what is going on.
12878                                            if (adj > clientAdj) {
12879                                                adjType = "bound-bg-services";
12880                                            }
12881                                            clientAdj = adj;
12882                                        }
12883                                    }
12884                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12885                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12886                                        // If this connection is keeping the service
12887                                        // created, then we want to try to better follow
12888                                        // its memory management semantics for activities.
12889                                        // That is, if it is sitting in the background
12890                                        // LRU list as a hidden process (with activities),
12891                                        // we don't want the service it is connected to
12892                                        // to go into the empty LRU and quickly get killed,
12893                                        // because I'll we'll do is just end up restarting
12894                                        // the service.
12895                                        app.hasClientActivities |= client.hasActivities;
12896                                    }
12897                                }
12898                                if (adj > clientAdj) {
12899                                    // If this process has recently shown UI, and
12900                                    // the process that is binding to it is less
12901                                    // important than being visible, then we don't
12902                                    // care about the binding as much as we care
12903                                    // about letting this process get into the LRU
12904                                    // list to be killed and restarted if needed for
12905                                    // memory.
12906                                    if (app.hasShownUi && app != mHomeProcess
12907                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12908                                        adjType = "bound-bg-ui-services";
12909                                    } else {
12910                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12911                                                |Context.BIND_IMPORTANT)) != 0) {
12912                                            adj = clientAdj;
12913                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12914                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12915                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12916                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12917                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12918                                            adj = clientAdj;
12919                                        } else {
12920                                            app.pendingUiClean = true;
12921                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12922                                                adj = ProcessList.VISIBLE_APP_ADJ;
12923                                            }
12924                                        }
12925                                        if (!client.hidden) {
12926                                            app.hidden = false;
12927                                        }
12928                                        if (client.keeping) {
12929                                            app.keeping = true;
12930                                        }
12931                                        adjType = "service";
12932                                    }
12933                                }
12934                                if (adjType != null) {
12935                                    app.adjType = adjType;
12936                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12937                                            .REASON_SERVICE_IN_USE;
12938                                    app.adjSource = cr.binding.client;
12939                                    app.adjSourceOom = clientAdj;
12940                                    app.adjTarget = s.name;
12941                                }
12942                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12943                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12944                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12945                                    }
12946                                }
12947                            }
12948                            final ActivityRecord a = cr.activity;
12949                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12950                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12951                                        (a.visible || a.state == ActivityState.RESUMED
12952                                         || a.state == ActivityState.PAUSING)) {
12953                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12954                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12955                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12956                                    }
12957                                    app.hidden = false;
12958                                    app.adjType = "service";
12959                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12960                                            .REASON_SERVICE_IN_USE;
12961                                    app.adjSource = a;
12962                                    app.adjSourceOom = adj;
12963                                    app.adjTarget = s.name;
12964                                }
12965                            }
12966                        }
12967                    }
12968                }
12969            }
12970
12971            // Finally, if this process has active services running in it, we
12972            // would like to avoid killing it unless it would prevent the current
12973            // application from running.  By default we put the process in
12974            // with the rest of the background processes; as we scan through
12975            // its services we may bump it up from there.
12976            if (adj > hiddenAdj) {
12977                adj = hiddenAdj;
12978                app.hidden = false;
12979                app.adjType = "bg-services";
12980            }
12981        }
12982
12983        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12984                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12985            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12986            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12987                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12988                ContentProviderRecord cpr = jt.next();
12989                for (int i = cpr.connections.size()-1;
12990                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12991                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12992                        i--) {
12993                    ContentProviderConnection conn = cpr.connections.get(i);
12994                    ProcessRecord client = conn.client;
12995                    if (client == app) {
12996                        // Being our own client is not interesting.
12997                        continue;
12998                    }
12999                    int myHiddenAdj = hiddenAdj;
13000                    if (myHiddenAdj > client.hiddenAdj) {
13001                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13002                            myHiddenAdj = client.hiddenAdj;
13003                        } else {
13004                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13005                        }
13006                    }
13007                    int myClientHiddenAdj = clientHiddenAdj;
13008                    if (myClientHiddenAdj > client.clientHiddenAdj) {
13009                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13010                            myClientHiddenAdj = client.clientHiddenAdj;
13011                        } else {
13012                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13013                        }
13014                    }
13015                    int myEmptyAdj = emptyAdj;
13016                    if (myEmptyAdj > client.emptyAdj) {
13017                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13018                            myEmptyAdj = client.emptyAdj;
13019                        } else {
13020                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13021                        }
13022                    }
13023                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13024                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13025                    if (adj > clientAdj) {
13026                        if (app.hasShownUi && app != mHomeProcess
13027                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13028                            app.adjType = "bg-ui-provider";
13029                        } else {
13030                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13031                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13032                            app.adjType = "provider";
13033                        }
13034                        if (!client.hidden) {
13035                            app.hidden = false;
13036                        }
13037                        if (client.keeping) {
13038                            app.keeping = true;
13039                        }
13040                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13041                                .REASON_PROVIDER_IN_USE;
13042                        app.adjSource = client;
13043                        app.adjSourceOom = clientAdj;
13044                        app.adjTarget = cpr.name;
13045                    }
13046                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13047                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13048                    }
13049                }
13050                // If the provider has external (non-framework) process
13051                // dependencies, ensure that its adjustment is at least
13052                // FOREGROUND_APP_ADJ.
13053                if (cpr.hasExternalProcessHandles()) {
13054                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13055                        adj = ProcessList.FOREGROUND_APP_ADJ;
13056                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13057                        app.hidden = false;
13058                        app.keeping = true;
13059                        app.adjType = "provider";
13060                        app.adjTarget = cpr.name;
13061                    }
13062                }
13063            }
13064        }
13065
13066        if (adj == ProcessList.SERVICE_ADJ) {
13067            if (doingAll) {
13068                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13069                mNewNumServiceProcs++;
13070            }
13071            if (app.serviceb) {
13072                adj = ProcessList.SERVICE_B_ADJ;
13073            }
13074        } else {
13075            app.serviceb = false;
13076        }
13077
13078        app.nonStoppingAdj = adj;
13079
13080        if (hasStoppingActivities) {
13081            // Only upgrade adjustment.
13082            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13083                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13084                app.adjType = "stopping";
13085            }
13086        }
13087
13088        app.curRawAdj = adj;
13089
13090        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13091        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13092        if (adj > app.maxAdj) {
13093            adj = app.maxAdj;
13094            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13095                schedGroup = Process.THREAD_GROUP_DEFAULT;
13096            }
13097        }
13098        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13099            app.keeping = true;
13100        }
13101
13102        if (app.hasAboveClient) {
13103            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13104            // then we need to drop its adjustment to be lower than the service's
13105            // in order to honor the request.  We want to drop it by one adjustment
13106            // level...  but there is special meaning applied to various levels so
13107            // we will skip some of them.
13108            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13109                // System process will not get dropped, ever
13110            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13111                adj = ProcessList.VISIBLE_APP_ADJ;
13112            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13113                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13114            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13115                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13116            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13117                adj++;
13118            }
13119        }
13120
13121        int importance = app.memImportance;
13122        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13123            app.curAdj = adj;
13124            app.curSchedGroup = schedGroup;
13125            if (!interesting) {
13126                // For this reporting, if there is not something explicitly
13127                // interesting in this process then we will push it to the
13128                // background importance.
13129                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13130            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13131                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13132            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13133                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13134            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13135                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13136            } else if (adj >= ProcessList.SERVICE_ADJ) {
13137                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13138            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13139                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13140            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13141                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13142            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13143                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13144            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13145                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13146            } else {
13147                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13148            }
13149        }
13150
13151        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13152        if (foregroundActivities != app.foregroundActivities) {
13153            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13154        }
13155        if (changes != 0) {
13156            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13157            app.memImportance = importance;
13158            app.foregroundActivities = foregroundActivities;
13159            int i = mPendingProcessChanges.size()-1;
13160            ProcessChangeItem item = null;
13161            while (i >= 0) {
13162                item = mPendingProcessChanges.get(i);
13163                if (item.pid == app.pid) {
13164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13165                    break;
13166                }
13167                i--;
13168            }
13169            if (i < 0) {
13170                // No existing item in pending changes; need a new one.
13171                final int NA = mAvailProcessChanges.size();
13172                if (NA > 0) {
13173                    item = mAvailProcessChanges.remove(NA-1);
13174                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13175                } else {
13176                    item = new ProcessChangeItem();
13177                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13178                }
13179                item.changes = 0;
13180                item.pid = app.pid;
13181                item.uid = app.info.uid;
13182                if (mPendingProcessChanges.size() == 0) {
13183                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13184                            "*** Enqueueing dispatch processes changed!");
13185                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13186                }
13187                mPendingProcessChanges.add(item);
13188            }
13189            item.changes |= changes;
13190            item.importance = importance;
13191            item.foregroundActivities = foregroundActivities;
13192            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13193                    + Integer.toHexString(System.identityHashCode(item))
13194                    + " " + app.toShortString() + ": changes=" + item.changes
13195                    + " importance=" + item.importance
13196                    + " foreground=" + item.foregroundActivities
13197                    + " type=" + app.adjType + " source=" + app.adjSource
13198                    + " target=" + app.adjTarget);
13199        }
13200
13201        return app.curRawAdj;
13202    }
13203
13204    /**
13205     * Ask a given process to GC right now.
13206     */
13207    final void performAppGcLocked(ProcessRecord app) {
13208        try {
13209            app.lastRequestedGc = SystemClock.uptimeMillis();
13210            if (app.thread != null) {
13211                if (app.reportLowMemory) {
13212                    app.reportLowMemory = false;
13213                    app.thread.scheduleLowMemory();
13214                } else {
13215                    app.thread.processInBackground();
13216                }
13217            }
13218        } catch (Exception e) {
13219            // whatever.
13220        }
13221    }
13222
13223    /**
13224     * Returns true if things are idle enough to perform GCs.
13225     */
13226    private final boolean canGcNowLocked() {
13227        boolean processingBroadcasts = false;
13228        for (BroadcastQueue q : mBroadcastQueues) {
13229            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13230                processingBroadcasts = true;
13231            }
13232        }
13233        return !processingBroadcasts
13234                && (mSleeping || (mMainStack.mResumedActivity != null &&
13235                        mMainStack.mResumedActivity.idle));
13236    }
13237
13238    /**
13239     * Perform GCs on all processes that are waiting for it, but only
13240     * if things are idle.
13241     */
13242    final void performAppGcsLocked() {
13243        final int N = mProcessesToGc.size();
13244        if (N <= 0) {
13245            return;
13246        }
13247        if (canGcNowLocked()) {
13248            while (mProcessesToGc.size() > 0) {
13249                ProcessRecord proc = mProcessesToGc.remove(0);
13250                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13251                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13252                            <= SystemClock.uptimeMillis()) {
13253                        // To avoid spamming the system, we will GC processes one
13254                        // at a time, waiting a few seconds between each.
13255                        performAppGcLocked(proc);
13256                        scheduleAppGcsLocked();
13257                        return;
13258                    } else {
13259                        // It hasn't been long enough since we last GCed this
13260                        // process...  put it in the list to wait for its time.
13261                        addProcessToGcListLocked(proc);
13262                        break;
13263                    }
13264                }
13265            }
13266
13267            scheduleAppGcsLocked();
13268        }
13269    }
13270
13271    /**
13272     * If all looks good, perform GCs on all processes waiting for them.
13273     */
13274    final void performAppGcsIfAppropriateLocked() {
13275        if (canGcNowLocked()) {
13276            performAppGcsLocked();
13277            return;
13278        }
13279        // Still not idle, wait some more.
13280        scheduleAppGcsLocked();
13281    }
13282
13283    /**
13284     * Schedule the execution of all pending app GCs.
13285     */
13286    final void scheduleAppGcsLocked() {
13287        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13288
13289        if (mProcessesToGc.size() > 0) {
13290            // Schedule a GC for the time to the next process.
13291            ProcessRecord proc = mProcessesToGc.get(0);
13292            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13293
13294            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13295            long now = SystemClock.uptimeMillis();
13296            if (when < (now+GC_TIMEOUT)) {
13297                when = now + GC_TIMEOUT;
13298            }
13299            mHandler.sendMessageAtTime(msg, when);
13300        }
13301    }
13302
13303    /**
13304     * Add a process to the array of processes waiting to be GCed.  Keeps the
13305     * list in sorted order by the last GC time.  The process can't already be
13306     * on the list.
13307     */
13308    final void addProcessToGcListLocked(ProcessRecord proc) {
13309        boolean added = false;
13310        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13311            if (mProcessesToGc.get(i).lastRequestedGc <
13312                    proc.lastRequestedGc) {
13313                added = true;
13314                mProcessesToGc.add(i+1, proc);
13315                break;
13316            }
13317        }
13318        if (!added) {
13319            mProcessesToGc.add(0, proc);
13320        }
13321    }
13322
13323    /**
13324     * Set up to ask a process to GC itself.  This will either do it
13325     * immediately, or put it on the list of processes to gc the next
13326     * time things are idle.
13327     */
13328    final void scheduleAppGcLocked(ProcessRecord app) {
13329        long now = SystemClock.uptimeMillis();
13330        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13331            return;
13332        }
13333        if (!mProcessesToGc.contains(app)) {
13334            addProcessToGcListLocked(app);
13335            scheduleAppGcsLocked();
13336        }
13337    }
13338
13339    final void checkExcessivePowerUsageLocked(boolean doKills) {
13340        updateCpuStatsNow();
13341
13342        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13343        boolean doWakeKills = doKills;
13344        boolean doCpuKills = doKills;
13345        if (mLastPowerCheckRealtime == 0) {
13346            doWakeKills = false;
13347        }
13348        if (mLastPowerCheckUptime == 0) {
13349            doCpuKills = false;
13350        }
13351        if (stats.isScreenOn()) {
13352            doWakeKills = false;
13353        }
13354        final long curRealtime = SystemClock.elapsedRealtime();
13355        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13356        final long curUptime = SystemClock.uptimeMillis();
13357        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13358        mLastPowerCheckRealtime = curRealtime;
13359        mLastPowerCheckUptime = curUptime;
13360        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13361            doWakeKills = false;
13362        }
13363        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13364            doCpuKills = false;
13365        }
13366        int i = mLruProcesses.size();
13367        while (i > 0) {
13368            i--;
13369            ProcessRecord app = mLruProcesses.get(i);
13370            if (!app.keeping) {
13371                long wtime;
13372                synchronized (stats) {
13373                    wtime = stats.getProcessWakeTime(app.info.uid,
13374                            app.pid, curRealtime);
13375                }
13376                long wtimeUsed = wtime - app.lastWakeTime;
13377                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13378                if (DEBUG_POWER) {
13379                    StringBuilder sb = new StringBuilder(128);
13380                    sb.append("Wake for ");
13381                    app.toShortString(sb);
13382                    sb.append(": over ");
13383                    TimeUtils.formatDuration(realtimeSince, sb);
13384                    sb.append(" used ");
13385                    TimeUtils.formatDuration(wtimeUsed, sb);
13386                    sb.append(" (");
13387                    sb.append((wtimeUsed*100)/realtimeSince);
13388                    sb.append("%)");
13389                    Slog.i(TAG, sb.toString());
13390                    sb.setLength(0);
13391                    sb.append("CPU for ");
13392                    app.toShortString(sb);
13393                    sb.append(": over ");
13394                    TimeUtils.formatDuration(uptimeSince, sb);
13395                    sb.append(" used ");
13396                    TimeUtils.formatDuration(cputimeUsed, sb);
13397                    sb.append(" (");
13398                    sb.append((cputimeUsed*100)/uptimeSince);
13399                    sb.append("%)");
13400                    Slog.i(TAG, sb.toString());
13401                }
13402                // If a process has held a wake lock for more
13403                // than 50% of the time during this period,
13404                // that sounds bad.  Kill!
13405                if (doWakeKills && realtimeSince > 0
13406                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13407                    synchronized (stats) {
13408                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13409                                realtimeSince, wtimeUsed);
13410                    }
13411                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13412                            + " (pid " + app.pid + "): held " + wtimeUsed
13413                            + " during " + realtimeSince);
13414                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13415                            app.processName, app.setAdj, "excessive wake lock");
13416                    Process.killProcessQuiet(app.pid);
13417                } else if (doCpuKills && uptimeSince > 0
13418                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13419                    synchronized (stats) {
13420                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13421                                uptimeSince, cputimeUsed);
13422                    }
13423                    Slog.w(TAG, "Excessive CPU in " + app.processName
13424                            + " (pid " + app.pid + "): used " + cputimeUsed
13425                            + " during " + uptimeSince);
13426                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13427                            app.processName, app.setAdj, "excessive cpu");
13428                    Process.killProcessQuiet(app.pid);
13429                } else {
13430                    app.lastWakeTime = wtime;
13431                    app.lastCpuTime = app.curCpuTime;
13432                }
13433            }
13434        }
13435    }
13436
13437    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13438            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13439        app.hiddenAdj = hiddenAdj;
13440        app.clientHiddenAdj = clientHiddenAdj;
13441        app.emptyAdj = emptyAdj;
13442
13443        if (app.thread == null) {
13444            return false;
13445        }
13446
13447        final boolean wasKeeping = app.keeping;
13448
13449        boolean success = true;
13450
13451        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13452
13453        if (app.curRawAdj != app.setRawAdj) {
13454            if (wasKeeping && !app.keeping) {
13455                // This app is no longer something we want to keep.  Note
13456                // its current wake lock time to later know to kill it if
13457                // it is not behaving well.
13458                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13459                synchronized (stats) {
13460                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13461                            app.pid, SystemClock.elapsedRealtime());
13462                }
13463                app.lastCpuTime = app.curCpuTime;
13464            }
13465
13466            app.setRawAdj = app.curRawAdj;
13467        }
13468
13469        if (app.curAdj != app.setAdj) {
13470            if (Process.setOomAdj(app.pid, app.curAdj)) {
13471                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13472                    TAG, "Set " + app.pid + " " + app.processName +
13473                    " adj " + app.curAdj + ": " + app.adjType);
13474                app.setAdj = app.curAdj;
13475            } else {
13476                success = false;
13477                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13478            }
13479        }
13480        if (app.setSchedGroup != app.curSchedGroup) {
13481            app.setSchedGroup = app.curSchedGroup;
13482            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13483                    "Setting process group of " + app.processName
13484                    + " to " + app.curSchedGroup);
13485            if (app.waitingToKill != null &&
13486                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13487                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13488                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13489                        app.processName, app.setAdj, app.waitingToKill);
13490                app.killedBackground = true;
13491                Process.killProcessQuiet(app.pid);
13492                success = false;
13493            } else {
13494                if (true) {
13495                    long oldId = Binder.clearCallingIdentity();
13496                    try {
13497                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13498                    } catch (Exception e) {
13499                        Slog.w(TAG, "Failed setting process group of " + app.pid
13500                                + " to " + app.curSchedGroup);
13501                        e.printStackTrace();
13502                    } finally {
13503                        Binder.restoreCallingIdentity(oldId);
13504                    }
13505                } else {
13506                    if (app.thread != null) {
13507                        try {
13508                            app.thread.setSchedulingGroup(app.curSchedGroup);
13509                        } catch (RemoteException e) {
13510                        }
13511                    }
13512                }
13513            }
13514        }
13515        return success;
13516    }
13517
13518    private final ActivityRecord resumedAppLocked() {
13519        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13520        if (resumedActivity == null || resumedActivity.app == null) {
13521            resumedActivity = mMainStack.mPausingActivity;
13522            if (resumedActivity == null || resumedActivity.app == null) {
13523                resumedActivity = mMainStack.topRunningActivityLocked(null);
13524            }
13525        }
13526        return resumedActivity;
13527    }
13528
13529    final boolean updateOomAdjLocked(ProcessRecord app) {
13530        final ActivityRecord TOP_ACT = resumedAppLocked();
13531        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13532        int curAdj = app.curAdj;
13533        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13534            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13535
13536        mAdjSeq++;
13537
13538        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13539                app.emptyAdj, TOP_APP, false);
13540        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13541            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13542        if (nowHidden != wasHidden) {
13543            // Changed to/from hidden state, so apps after it in the LRU
13544            // list may also be changed.
13545            updateOomAdjLocked();
13546        }
13547        return success;
13548    }
13549
13550    final void updateOomAdjLocked() {
13551        final ActivityRecord TOP_ACT = resumedAppLocked();
13552        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13553        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13554
13555        if (false) {
13556            RuntimeException e = new RuntimeException();
13557            e.fillInStackTrace();
13558            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13559        }
13560
13561        mAdjSeq++;
13562        mNewNumServiceProcs = 0;
13563
13564        final int emptyProcessLimit;
13565        final int hiddenProcessLimit;
13566        if (mProcessLimit <= 0) {
13567            emptyProcessLimit = hiddenProcessLimit = 0;
13568        } else if (mProcessLimit == 1) {
13569            emptyProcessLimit = 1;
13570            hiddenProcessLimit = 0;
13571        } else {
13572            emptyProcessLimit = (mProcessLimit*2)/3;
13573            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13574        }
13575
13576        // Let's determine how many processes we have running vs.
13577        // how many slots we have for background processes; we may want
13578        // to put multiple processes in a slot of there are enough of
13579        // them.
13580        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13581                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13582        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13583        if (numEmptyProcs > hiddenProcessLimit) {
13584            // If there are more empty processes than our limit on hidden
13585            // processes, then use the hidden process limit for the factor.
13586            // This ensures that the really old empty processes get pushed
13587            // down to the bottom, so if we are running low on memory we will
13588            // have a better chance at keeping around more hidden processes
13589            // instead of a gazillion empty processes.
13590            numEmptyProcs = hiddenProcessLimit;
13591        }
13592        int emptyFactor = numEmptyProcs/numSlots;
13593        if (emptyFactor < 1) emptyFactor = 1;
13594        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13595        if (hiddenFactor < 1) hiddenFactor = 1;
13596        int stepHidden = 0;
13597        int stepEmpty = 0;
13598        int numHidden = 0;
13599        int numEmpty = 0;
13600        int numTrimming = 0;
13601
13602        mNumNonHiddenProcs = 0;
13603        mNumHiddenProcs = 0;
13604
13605        // First update the OOM adjustment for each of the
13606        // application processes based on their current state.
13607        int i = mLruProcesses.size();
13608        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13609        int nextHiddenAdj = curHiddenAdj+1;
13610        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13611        int nextEmptyAdj = curEmptyAdj+2;
13612        int curClientHiddenAdj = curEmptyAdj;
13613        while (i > 0) {
13614            i--;
13615            ProcessRecord app = mLruProcesses.get(i);
13616            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13617            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13618            if (!app.killedBackground) {
13619                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13620                    // This process was assigned as a hidden process...  step the
13621                    // hidden level.
13622                    mNumHiddenProcs++;
13623                    if (curHiddenAdj != nextHiddenAdj) {
13624                        stepHidden++;
13625                        if (stepHidden >= hiddenFactor) {
13626                            stepHidden = 0;
13627                            curHiddenAdj = nextHiddenAdj;
13628                            nextHiddenAdj += 2;
13629                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13630                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13631                            }
13632                            if (curClientHiddenAdj <= curHiddenAdj) {
13633                                curClientHiddenAdj = curHiddenAdj + 1;
13634                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13635                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13636                                }
13637                            }
13638                        }
13639                    }
13640                    numHidden++;
13641                    if (numHidden > hiddenProcessLimit) {
13642                        Slog.i(TAG, "No longer want " + app.processName
13643                                + " (pid " + app.pid + "): hidden #" + numHidden);
13644                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13645                                app.processName, app.setAdj, "too many background");
13646                        app.killedBackground = true;
13647                        Process.killProcessQuiet(app.pid);
13648                    }
13649                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13650                    // This process has a client that has activities.  We will have
13651                    // given it the current hidden adj; here we will just leave it
13652                    // without stepping the hidden adj.
13653                    curClientHiddenAdj++;
13654                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13655                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13656                    }
13657                } else {
13658                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13659                        // This process was assigned as an empty process...  step the
13660                        // empty level.
13661                        if (curEmptyAdj != nextEmptyAdj) {
13662                            stepEmpty++;
13663                            if (stepEmpty >= emptyFactor) {
13664                                stepEmpty = 0;
13665                                curEmptyAdj = nextEmptyAdj;
13666                                nextEmptyAdj += 2;
13667                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13668                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13669                                }
13670                            }
13671                        }
13672                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13673                        mNumNonHiddenProcs++;
13674                    }
13675                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13676                            && !app.hasClientActivities) {
13677                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13678                                && app.lastActivityTime < oldTime) {
13679                            Slog.i(TAG, "No longer want " + app.processName
13680                                    + " (pid " + app.pid + "): empty for "
13681                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13682                                            / 1000) + "s");
13683                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13684                                    app.processName, app.setAdj, "old background process");
13685                            app.killedBackground = true;
13686                            Process.killProcessQuiet(app.pid);
13687                        } else {
13688                            numEmpty++;
13689                            if (numEmpty > emptyProcessLimit) {
13690                                Slog.i(TAG, "No longer want " + app.processName
13691                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13692                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13693                                        app.processName, app.setAdj, "too many background");
13694                                app.killedBackground = true;
13695                                Process.killProcessQuiet(app.pid);
13696                            }
13697                        }
13698                    }
13699                }
13700                if (app.isolated && app.services.size() <= 0) {
13701                    // If this is an isolated process, and there are no
13702                    // services running in it, then the process is no longer
13703                    // needed.  We agressively kill these because we can by
13704                    // definition not re-use the same process again, and it is
13705                    // good to avoid having whatever code was running in them
13706                    // left sitting around after no longer needed.
13707                    Slog.i(TAG, "Isolated process " + app.processName
13708                            + " (pid " + app.pid + ") no longer needed");
13709                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13710                            app.processName, app.setAdj, "isolated not needed");
13711                    app.killedBackground = true;
13712                    Process.killProcessQuiet(app.pid);
13713                }
13714                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13715                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13716                        && !app.killedBackground) {
13717                    numTrimming++;
13718                }
13719            }
13720        }
13721
13722        mNumServiceProcs = mNewNumServiceProcs;
13723
13724        // Now determine the memory trimming level of background processes.
13725        // Unfortunately we need to start at the back of the list to do this
13726        // properly.  We only do this if the number of background apps we
13727        // are managing to keep around is less than half the maximum we desire;
13728        // if we are keeping a good number around, we'll let them use whatever
13729        // memory they want.
13730        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13731                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13732            final int numHiddenAndEmpty = numHidden + numEmpty;
13733            final int N = mLruProcesses.size();
13734            int factor = numTrimming/3;
13735            int minFactor = 2;
13736            if (mHomeProcess != null) minFactor++;
13737            if (mPreviousProcess != null) minFactor++;
13738            if (factor < minFactor) factor = minFactor;
13739            int step = 0;
13740            int fgTrimLevel;
13741            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13742                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13743            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13744                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13745            } else {
13746                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13747            }
13748            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13749            for (i=0; i<N; i++) {
13750                ProcessRecord app = mLruProcesses.get(i);
13751                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13752                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13753                        && !app.killedBackground) {
13754                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13755                        try {
13756                            app.thread.scheduleTrimMemory(curLevel);
13757                        } catch (RemoteException e) {
13758                        }
13759                        if (false) {
13760                            // For now we won't do this; our memory trimming seems
13761                            // to be good enough at this point that destroying
13762                            // activities causes more harm than good.
13763                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13764                                    && app != mHomeProcess && app != mPreviousProcess) {
13765                                // Need to do this on its own message because the stack may not
13766                                // be in a consistent state at this point.
13767                                // For these apps we will also finish their activities
13768                                // to help them free memory.
13769                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13770                            }
13771                        }
13772                    }
13773                    app.trimMemoryLevel = curLevel;
13774                    step++;
13775                    if (step >= factor) {
13776                        step = 0;
13777                        switch (curLevel) {
13778                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13779                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13780                                break;
13781                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13782                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13783                                break;
13784                        }
13785                    }
13786                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13787                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13788                            && app.thread != null) {
13789                        try {
13790                            app.thread.scheduleTrimMemory(
13791                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13792                        } catch (RemoteException e) {
13793                        }
13794                    }
13795                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13796                } else {
13797                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13798                            && app.pendingUiClean) {
13799                        // If this application is now in the background and it
13800                        // had done UI, then give it the special trim level to
13801                        // have it free UI resources.
13802                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13803                        if (app.trimMemoryLevel < level && app.thread != null) {
13804                            try {
13805                                app.thread.scheduleTrimMemory(level);
13806                            } catch (RemoteException e) {
13807                            }
13808                        }
13809                        app.pendingUiClean = false;
13810                    }
13811                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13812                        try {
13813                            app.thread.scheduleTrimMemory(fgTrimLevel);
13814                        } catch (RemoteException e) {
13815                        }
13816                    }
13817                    app.trimMemoryLevel = fgTrimLevel;
13818                }
13819            }
13820        } else {
13821            final int N = mLruProcesses.size();
13822            for (i=0; i<N; i++) {
13823                ProcessRecord app = mLruProcesses.get(i);
13824                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13825                        && app.pendingUiClean) {
13826                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13827                            && app.thread != null) {
13828                        try {
13829                            app.thread.scheduleTrimMemory(
13830                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13831                        } catch (RemoteException e) {
13832                        }
13833                    }
13834                    app.pendingUiClean = false;
13835                }
13836                app.trimMemoryLevel = 0;
13837            }
13838        }
13839
13840        if (mAlwaysFinishActivities) {
13841            // Need to do this on its own message because the stack may not
13842            // be in a consistent state at this point.
13843            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13844        }
13845    }
13846
13847    final void trimApplications() {
13848        synchronized (this) {
13849            int i;
13850
13851            // First remove any unused application processes whose package
13852            // has been removed.
13853            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13854                final ProcessRecord app = mRemovedProcesses.get(i);
13855                if (app.activities.size() == 0
13856                        && app.curReceiver == null && app.services.size() == 0) {
13857                    Slog.i(
13858                        TAG, "Exiting empty application process "
13859                        + app.processName + " ("
13860                        + (app.thread != null ? app.thread.asBinder() : null)
13861                        + ")\n");
13862                    if (app.pid > 0 && app.pid != MY_PID) {
13863                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13864                                app.processName, app.setAdj, "empty");
13865                        Process.killProcessQuiet(app.pid);
13866                    } else {
13867                        try {
13868                            app.thread.scheduleExit();
13869                        } catch (Exception e) {
13870                            // Ignore exceptions.
13871                        }
13872                    }
13873                    cleanUpApplicationRecordLocked(app, false, true, -1);
13874                    mRemovedProcesses.remove(i);
13875
13876                    if (app.persistent) {
13877                        if (app.persistent) {
13878                            addAppLocked(app.info, false);
13879                        }
13880                    }
13881                }
13882            }
13883
13884            // Now update the oom adj for all processes.
13885            updateOomAdjLocked();
13886        }
13887    }
13888
13889    /** This method sends the specified signal to each of the persistent apps */
13890    public void signalPersistentProcesses(int sig) throws RemoteException {
13891        if (sig != Process.SIGNAL_USR1) {
13892            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13893        }
13894
13895        synchronized (this) {
13896            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13897                    != PackageManager.PERMISSION_GRANTED) {
13898                throw new SecurityException("Requires permission "
13899                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13900            }
13901
13902            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13903                ProcessRecord r = mLruProcesses.get(i);
13904                if (r.thread != null && r.persistent) {
13905                    Process.sendSignal(r.pid, sig);
13906                }
13907            }
13908        }
13909    }
13910
13911    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13912        if (proc == null || proc == mProfileProc) {
13913            proc = mProfileProc;
13914            path = mProfileFile;
13915            profileType = mProfileType;
13916            clearProfilerLocked();
13917        }
13918        if (proc == null) {
13919            return;
13920        }
13921        try {
13922            proc.thread.profilerControl(false, path, null, profileType);
13923        } catch (RemoteException e) {
13924            throw new IllegalStateException("Process disappeared");
13925        }
13926    }
13927
13928    private void clearProfilerLocked() {
13929        if (mProfileFd != null) {
13930            try {
13931                mProfileFd.close();
13932            } catch (IOException e) {
13933            }
13934        }
13935        mProfileApp = null;
13936        mProfileProc = null;
13937        mProfileFile = null;
13938        mProfileType = 0;
13939        mAutoStopProfiler = false;
13940    }
13941
13942    public boolean profileControl(String process, int userId, boolean start,
13943            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13944
13945        try {
13946            synchronized (this) {
13947                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13948                // its own permission.
13949                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13950                        != PackageManager.PERMISSION_GRANTED) {
13951                    throw new SecurityException("Requires permission "
13952                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13953                }
13954
13955                if (start && fd == null) {
13956                    throw new IllegalArgumentException("null fd");
13957                }
13958
13959                ProcessRecord proc = null;
13960                if (process != null) {
13961                    proc = findProcessLocked(process, userId, "profileControl");
13962                }
13963
13964                if (start && (proc == null || proc.thread == null)) {
13965                    throw new IllegalArgumentException("Unknown process: " + process);
13966                }
13967
13968                if (start) {
13969                    stopProfilerLocked(null, null, 0);
13970                    setProfileApp(proc.info, proc.processName, path, fd, false);
13971                    mProfileProc = proc;
13972                    mProfileType = profileType;
13973                    try {
13974                        fd = fd.dup();
13975                    } catch (IOException e) {
13976                        fd = null;
13977                    }
13978                    proc.thread.profilerControl(start, path, fd, profileType);
13979                    fd = null;
13980                    mProfileFd = null;
13981                } else {
13982                    stopProfilerLocked(proc, path, profileType);
13983                    if (fd != null) {
13984                        try {
13985                            fd.close();
13986                        } catch (IOException e) {
13987                        }
13988                    }
13989                }
13990
13991                return true;
13992            }
13993        } catch (RemoteException e) {
13994            throw new IllegalStateException("Process disappeared");
13995        } finally {
13996            if (fd != null) {
13997                try {
13998                    fd.close();
13999                } catch (IOException e) {
14000                }
14001            }
14002        }
14003    }
14004
14005    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14006        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14007                userId, true, true, callName, null);
14008        ProcessRecord proc = null;
14009        try {
14010            int pid = Integer.parseInt(process);
14011            synchronized (mPidsSelfLocked) {
14012                proc = mPidsSelfLocked.get(pid);
14013            }
14014        } catch (NumberFormatException e) {
14015        }
14016
14017        if (proc == null) {
14018            HashMap<String, SparseArray<ProcessRecord>> all
14019                    = mProcessNames.getMap();
14020            SparseArray<ProcessRecord> procs = all.get(process);
14021            if (procs != null && procs.size() > 0) {
14022                proc = procs.valueAt(0);
14023                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14024                    for (int i=1; i<procs.size(); i++) {
14025                        ProcessRecord thisProc = procs.valueAt(i);
14026                        if (thisProc.userId == userId) {
14027                            proc = thisProc;
14028                            break;
14029                        }
14030                    }
14031                }
14032            }
14033        }
14034
14035        return proc;
14036    }
14037
14038    public boolean dumpHeap(String process, int userId, boolean managed,
14039            String path, ParcelFileDescriptor fd) throws RemoteException {
14040
14041        try {
14042            synchronized (this) {
14043                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14044                // its own permission (same as profileControl).
14045                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14046                        != PackageManager.PERMISSION_GRANTED) {
14047                    throw new SecurityException("Requires permission "
14048                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14049                }
14050
14051                if (fd == null) {
14052                    throw new IllegalArgumentException("null fd");
14053                }
14054
14055                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14056                if (proc == null || proc.thread == null) {
14057                    throw new IllegalArgumentException("Unknown process: " + process);
14058                }
14059
14060                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14061                if (!isDebuggable) {
14062                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14063                        throw new SecurityException("Process not debuggable: " + proc);
14064                    }
14065                }
14066
14067                proc.thread.dumpHeap(managed, path, fd);
14068                fd = null;
14069                return true;
14070            }
14071        } catch (RemoteException e) {
14072            throw new IllegalStateException("Process disappeared");
14073        } finally {
14074            if (fd != null) {
14075                try {
14076                    fd.close();
14077                } catch (IOException e) {
14078                }
14079            }
14080        }
14081    }
14082
14083    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14084    public void monitor() {
14085        synchronized (this) { }
14086    }
14087
14088    void onCoreSettingsChange(Bundle settings) {
14089        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14090            ProcessRecord processRecord = mLruProcesses.get(i);
14091            try {
14092                if (processRecord.thread != null) {
14093                    processRecord.thread.setCoreSettings(settings);
14094                }
14095            } catch (RemoteException re) {
14096                /* ignore */
14097            }
14098        }
14099    }
14100
14101    // Multi-user methods
14102
14103    @Override
14104    public boolean switchUser(int userId) {
14105        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14106                != PackageManager.PERMISSION_GRANTED) {
14107            String msg = "Permission Denial: switchUser() from pid="
14108                    + Binder.getCallingPid()
14109                    + ", uid=" + Binder.getCallingUid()
14110                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14111            Slog.w(TAG, msg);
14112            throw new SecurityException(msg);
14113        }
14114
14115        final long ident = Binder.clearCallingIdentity();
14116        try {
14117            synchronized (this) {
14118                final int oldUserId = mCurrentUserId;
14119                if (oldUserId == userId) {
14120                    return true;
14121                }
14122
14123                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14124                if (userInfo == null) {
14125                    Slog.w(TAG, "No user info for user #" + userId);
14126                    return false;
14127                }
14128
14129                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14130                        R.anim.screen_user_enter);
14131
14132                boolean needStart = false;
14133
14134                // If the user we are switching to is not currently started, then
14135                // we need to start it now.
14136                if (mStartedUsers.get(userId) == null) {
14137                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14138                    updateStartedUserArrayLocked();
14139                    needStart = true;
14140                }
14141
14142                mCurrentUserId = userId;
14143                mCurrentUserArray = new int[] { userId };
14144                final Integer userIdInt = Integer.valueOf(userId);
14145                mUserLru.remove(userIdInt);
14146                mUserLru.add(userIdInt);
14147
14148                mWindowManager.setCurrentUser(userId);
14149
14150                // Once the internal notion of the active user has switched, we lock the device
14151                // with the option to show the user switcher on the keyguard.
14152                mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
14153
14154                final UserStartedState uss = mStartedUsers.get(userId);
14155
14156                // Make sure user is in the started state.  If it is currently
14157                // stopping, we need to knock that off.
14158                if (uss.mState == UserStartedState.STATE_STOPPING) {
14159                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14160                    // so we can just fairly silently bring the user back from
14161                    // the almost-dead.
14162                    uss.mState = UserStartedState.STATE_RUNNING;
14163                    updateStartedUserArrayLocked();
14164                    needStart = true;
14165                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14166                    // This means ACTION_SHUTDOWN has been sent, so we will
14167                    // need to treat this as a new boot of the user.
14168                    uss.mState = UserStartedState.STATE_BOOTING;
14169                    updateStartedUserArrayLocked();
14170                    needStart = true;
14171                }
14172
14173                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14174                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14175                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14176                        oldUserId, userId, uss));
14177                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14178                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14179                if (needStart) {
14180                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14181                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14182                            | Intent.FLAG_RECEIVER_FOREGROUND);
14183                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14184                    broadcastIntentLocked(null, null, intent,
14185                            null, null, 0, null, null, null,
14186                            false, false, MY_PID, Process.SYSTEM_UID, userId);
14187                }
14188
14189                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14190                    if (userId != 0) {
14191                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14192                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14193                        broadcastIntentLocked(null, null, intent, null,
14194                                new IIntentReceiver.Stub() {
14195                                    public void performReceive(Intent intent, int resultCode,
14196                                            String data, Bundle extras, boolean ordered,
14197                                            boolean sticky, int sendingUser) {
14198                                        userInitialized(uss);
14199                                    }
14200                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14201                                userId);
14202                        uss.initializing = true;
14203                    } else {
14204                        getUserManagerLocked().makeInitialized(userInfo.id);
14205                    }
14206                }
14207
14208                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14209                if (!haveActivities) {
14210                    startHomeActivityLocked(userId);
14211                }
14212
14213                getUserManagerLocked().userForeground(userId);
14214                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14215                if (needStart) {
14216                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14217                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14218                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14219                    broadcastIntentLocked(null, null, intent,
14220                            null, new IIntentReceiver.Stub() {
14221                                @Override
14222                                public void performReceive(Intent intent, int resultCode, String data,
14223                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14224                                        throws RemoteException {
14225                                }
14226                            }, 0, null, null,
14227                            android.Manifest.permission.INTERACT_ACROSS_USERS,
14228                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14229                }
14230            }
14231        } finally {
14232            Binder.restoreCallingIdentity(ident);
14233        }
14234
14235        return true;
14236    }
14237
14238    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14239        long ident = Binder.clearCallingIdentity();
14240        try {
14241            Intent intent;
14242            if (oldUserId >= 0) {
14243                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14244                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14245                        | Intent.FLAG_RECEIVER_FOREGROUND);
14246                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14247                broadcastIntentLocked(null, null, intent,
14248                        null, null, 0, null, null, null,
14249                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14250            }
14251            if (newUserId >= 0) {
14252                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14253                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14254                        | Intent.FLAG_RECEIVER_FOREGROUND);
14255                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14256                broadcastIntentLocked(null, null, intent,
14257                        null, null, 0, null, null, null,
14258                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14259                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14260                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14261                        | Intent.FLAG_RECEIVER_FOREGROUND);
14262                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14263                broadcastIntentLocked(null, null, intent,
14264                        null, null, 0, null, null,
14265                        android.Manifest.permission.MANAGE_USERS,
14266                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14267            }
14268        } finally {
14269            Binder.restoreCallingIdentity(ident);
14270        }
14271    }
14272
14273    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14274            final int newUserId) {
14275        final int N = mUserSwitchObservers.beginBroadcast();
14276        if (N > 0) {
14277            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14278                int mCount = 0;
14279                @Override
14280                public void sendResult(Bundle data) throws RemoteException {
14281                    synchronized (ActivityManagerService.this) {
14282                        if (mCurUserSwitchCallback == this) {
14283                            mCount++;
14284                            if (mCount == N) {
14285                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14286                            }
14287                        }
14288                    }
14289                }
14290            };
14291            synchronized (this) {
14292                uss.switching = true;
14293                mCurUserSwitchCallback = callback;
14294            }
14295            for (int i=0; i<N; i++) {
14296                try {
14297                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14298                            newUserId, callback);
14299                } catch (RemoteException e) {
14300                }
14301            }
14302        } else {
14303            synchronized (this) {
14304                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14305            }
14306        }
14307        mUserSwitchObservers.finishBroadcast();
14308    }
14309
14310    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14311        synchronized (this) {
14312            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14313            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14314        }
14315    }
14316
14317    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14318        mCurUserSwitchCallback = null;
14319        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14320        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14321                oldUserId, newUserId, uss));
14322    }
14323
14324    void userInitialized(UserStartedState uss) {
14325        synchronized (ActivityManagerService.this) {
14326            getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14327            uss.initializing = false;
14328            completeSwitchAndInitalizeLocked(uss);
14329        }
14330    }
14331
14332    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14333        final int N = mUserSwitchObservers.beginBroadcast();
14334        for (int i=0; i<N; i++) {
14335            try {
14336                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14337            } catch (RemoteException e) {
14338            }
14339        }
14340        mUserSwitchObservers.finishBroadcast();
14341        synchronized (this) {
14342            uss.switching = false;
14343            completeSwitchAndInitalizeLocked(uss);
14344        }
14345    }
14346
14347    void completeSwitchAndInitalizeLocked(UserStartedState uss) {
14348        if (!uss.switching && !uss.initializing) {
14349            mWindowManager.stopFreezingScreen();
14350        }
14351    }
14352
14353    void finishUserSwitch(UserStartedState uss) {
14354        synchronized (this) {
14355            if (uss.mState == UserStartedState.STATE_BOOTING
14356                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14357                uss.mState = UserStartedState.STATE_RUNNING;
14358                final int userId = uss.mHandle.getIdentifier();
14359                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14360                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14361                broadcastIntentLocked(null, null, intent,
14362                        null, null, 0, null, null,
14363                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14364                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14365            }
14366            int num = mUserLru.size();
14367            int i = 0;
14368            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14369                Integer oldUserId = mUserLru.get(i);
14370                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14371                if (oldUss == null) {
14372                    // Shouldn't happen, but be sane if it does.
14373                    mUserLru.remove(i);
14374                    num--;
14375                    continue;
14376                }
14377                if (oldUss.mState == UserStartedState.STATE_STOPPING
14378                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14379                    // This user is already stopping, doesn't count.
14380                    num--;
14381                    i++;
14382                    continue;
14383                }
14384                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14385                    // Owner and current can't be stopped, but count as running.
14386                    i++;
14387                    continue;
14388                }
14389                // This is a user to be stopped.
14390                stopUserLocked(oldUserId, null);
14391                num--;
14392                i++;
14393            }
14394        }
14395    }
14396
14397    @Override
14398    public int stopUser(final int userId, final IStopUserCallback callback) {
14399        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14400                != PackageManager.PERMISSION_GRANTED) {
14401            String msg = "Permission Denial: switchUser() from pid="
14402                    + Binder.getCallingPid()
14403                    + ", uid=" + Binder.getCallingUid()
14404                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14405            Slog.w(TAG, msg);
14406            throw new SecurityException(msg);
14407        }
14408        if (userId <= 0) {
14409            throw new IllegalArgumentException("Can't stop primary user " + userId);
14410        }
14411        synchronized (this) {
14412            return stopUserLocked(userId, callback);
14413        }
14414    }
14415
14416    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14417        if (mCurrentUserId == userId) {
14418            return ActivityManager.USER_OP_IS_CURRENT;
14419        }
14420
14421        final UserStartedState uss = mStartedUsers.get(userId);
14422        if (uss == null) {
14423            // User is not started, nothing to do...  but we do need to
14424            // callback if requested.
14425            if (callback != null) {
14426                mHandler.post(new Runnable() {
14427                    @Override
14428                    public void run() {
14429                        try {
14430                            callback.userStopped(userId);
14431                        } catch (RemoteException e) {
14432                        }
14433                    }
14434                });
14435            }
14436            return ActivityManager.USER_OP_SUCCESS;
14437        }
14438
14439        if (callback != null) {
14440            uss.mStopCallbacks.add(callback);
14441        }
14442
14443        if (uss.mState != UserStartedState.STATE_STOPPING
14444                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14445            uss.mState = UserStartedState.STATE_STOPPING;
14446            updateStartedUserArrayLocked();
14447
14448            long ident = Binder.clearCallingIdentity();
14449            try {
14450                // We are going to broadcast ACTION_USER_STOPPING and then
14451                // once that is down send a final ACTION_SHUTDOWN and then
14452                // stop the user.
14453                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14454                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14455                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14456                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14457                // This is the result receiver for the final shutdown broadcast.
14458                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14459                    @Override
14460                    public void performReceive(Intent intent, int resultCode, String data,
14461                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14462                        finishUserStop(uss);
14463                    }
14464                };
14465                // This is the result receiver for the initial stopping broadcast.
14466                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14467                    @Override
14468                    public void performReceive(Intent intent, int resultCode, String data,
14469                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14470                        // On to the next.
14471                        synchronized (ActivityManagerService.this) {
14472                            if (uss.mState != UserStartedState.STATE_STOPPING) {
14473                                // Whoops, we are being started back up.  Abort, abort!
14474                                return;
14475                            }
14476                            uss.mState = UserStartedState.STATE_SHUTDOWN;
14477                        }
14478                        broadcastIntentLocked(null, null, shutdownIntent,
14479                                null, shutdownReceiver, 0, null, null, null,
14480                                true, false, MY_PID, Process.SYSTEM_UID, userId);
14481                    }
14482                };
14483                // Kick things off.
14484                broadcastIntentLocked(null, null, stoppingIntent,
14485                        null, stoppingReceiver, 0, null, null,
14486                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14487                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14488            } finally {
14489                Binder.restoreCallingIdentity(ident);
14490            }
14491        }
14492
14493        return ActivityManager.USER_OP_SUCCESS;
14494    }
14495
14496    void finishUserStop(UserStartedState uss) {
14497        final int userId = uss.mHandle.getIdentifier();
14498        boolean stopped;
14499        ArrayList<IStopUserCallback> callbacks;
14500        synchronized (this) {
14501            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14502            if (mStartedUsers.get(userId) != uss) {
14503                stopped = false;
14504            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14505                stopped = false;
14506            } else {
14507                stopped = true;
14508                // User can no longer run.
14509                mStartedUsers.remove(userId);
14510                mUserLru.remove(Integer.valueOf(userId));
14511                updateStartedUserArrayLocked();
14512
14513                // Clean up all state and processes associated with the user.
14514                // Kill all the processes for the user.
14515                forceStopUserLocked(userId);
14516            }
14517        }
14518
14519        for (int i=0; i<callbacks.size(); i++) {
14520            try {
14521                if (stopped) callbacks.get(i).userStopped(userId);
14522                else callbacks.get(i).userStopAborted(userId);
14523            } catch (RemoteException e) {
14524            }
14525        }
14526    }
14527
14528    @Override
14529    public UserInfo getCurrentUser() {
14530        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14531                != PackageManager.PERMISSION_GRANTED) && (
14532                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14533                != PackageManager.PERMISSION_GRANTED)) {
14534            String msg = "Permission Denial: getCurrentUser() from pid="
14535                    + Binder.getCallingPid()
14536                    + ", uid=" + Binder.getCallingUid()
14537                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14538            Slog.w(TAG, msg);
14539            throw new SecurityException(msg);
14540        }
14541        synchronized (this) {
14542            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14543        }
14544    }
14545
14546    int getCurrentUserIdLocked() {
14547        return mCurrentUserId;
14548    }
14549
14550    @Override
14551    public boolean isUserRunning(int userId, boolean orStopped) {
14552        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14553                != PackageManager.PERMISSION_GRANTED) {
14554            String msg = "Permission Denial: isUserRunning() from pid="
14555                    + Binder.getCallingPid()
14556                    + ", uid=" + Binder.getCallingUid()
14557                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14558            Slog.w(TAG, msg);
14559            throw new SecurityException(msg);
14560        }
14561        synchronized (this) {
14562            return isUserRunningLocked(userId, orStopped);
14563        }
14564    }
14565
14566    boolean isUserRunningLocked(int userId, boolean orStopped) {
14567        UserStartedState state = mStartedUsers.get(userId);
14568        if (state == null) {
14569            return false;
14570        }
14571        if (orStopped) {
14572            return true;
14573        }
14574        return state.mState != UserStartedState.STATE_STOPPING
14575                && state.mState != UserStartedState.STATE_SHUTDOWN;
14576    }
14577
14578    @Override
14579    public int[] getRunningUserIds() {
14580        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14581                != PackageManager.PERMISSION_GRANTED) {
14582            String msg = "Permission Denial: isUserRunning() from pid="
14583                    + Binder.getCallingPid()
14584                    + ", uid=" + Binder.getCallingUid()
14585                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14586            Slog.w(TAG, msg);
14587            throw new SecurityException(msg);
14588        }
14589        synchronized (this) {
14590            return mStartedUserArray;
14591        }
14592    }
14593
14594    private void updateStartedUserArrayLocked() {
14595        int num = 0;
14596        for (int i=0; i<mStartedUsers.size();  i++) {
14597            UserStartedState uss = mStartedUsers.valueAt(i);
14598            // This list does not include stopping users.
14599            if (uss.mState != UserStartedState.STATE_STOPPING
14600                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14601                num++;
14602            }
14603        }
14604        mStartedUserArray = new int[num];
14605        num = 0;
14606        for (int i=0; i<mStartedUsers.size();  i++) {
14607            UserStartedState uss = mStartedUsers.valueAt(i);
14608            if (uss.mState != UserStartedState.STATE_STOPPING
14609                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14610                mStartedUserArray[num] = mStartedUsers.keyAt(i);
14611                num++;
14612            }
14613        }
14614    }
14615
14616    @Override
14617    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14618        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14619                != PackageManager.PERMISSION_GRANTED) {
14620            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14621                    + Binder.getCallingPid()
14622                    + ", uid=" + Binder.getCallingUid()
14623                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14624            Slog.w(TAG, msg);
14625            throw new SecurityException(msg);
14626        }
14627
14628        mUserSwitchObservers.register(observer);
14629    }
14630
14631    @Override
14632    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14633        mUserSwitchObservers.unregister(observer);
14634    }
14635
14636    private boolean userExists(int userId) {
14637        if (userId == 0) {
14638            return true;
14639        }
14640        UserManagerService ums = getUserManagerLocked();
14641        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14642    }
14643
14644    int[] getUsersLocked() {
14645        UserManagerService ums = getUserManagerLocked();
14646        return ums != null ? ums.getUserIds() : new int[] { 0 };
14647    }
14648
14649    UserManagerService getUserManagerLocked() {
14650        if (mUserManager == null) {
14651            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14652            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14653        }
14654        return mUserManager;
14655    }
14656
14657    private void checkValidCaller(int uid, int userId) {
14658        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14659
14660        throw new SecurityException("Caller uid=" + uid
14661                + " is not privileged to communicate with user=" + userId);
14662    }
14663
14664    private int applyUserId(int uid, int userId) {
14665        return UserHandle.getUid(userId, uid);
14666    }
14667
14668    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14669        if (info == null) return null;
14670        ApplicationInfo newInfo = new ApplicationInfo(info);
14671        newInfo.uid = applyUserId(info.uid, userId);
14672        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14673                + info.packageName;
14674        return newInfo;
14675    }
14676
14677    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14678        if (aInfo == null
14679                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14680            return aInfo;
14681        }
14682
14683        ActivityInfo info = new ActivityInfo(aInfo);
14684        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14685        return info;
14686    }
14687}
14688