ActivityManagerService.java revision f1b674197577e815040cd75ef86d611965d603ad
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.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IStopUserCallback;
51import android.app.IThumbnailReceiver;
52import android.app.IUserSwitchObserver;
53import android.app.Instrumentation;
54import android.app.Notification;
55import android.app.NotificationManager;
56import android.app.PendingIntent;
57import android.app.backup.IBackupManager;
58import android.content.ActivityNotFoundException;
59import android.content.BroadcastReceiver;
60import android.content.ClipData;
61import android.content.ComponentCallbacks2;
62import android.content.ComponentName;
63import android.content.ContentProvider;
64import android.content.ContentResolver;
65import android.content.Context;
66import android.content.DialogInterface;
67import android.content.IContentProvider;
68import android.content.IIntentReceiver;
69import android.content.IIntentSender;
70import android.content.Intent;
71import android.content.IntentFilter;
72import android.content.IntentSender;
73import android.content.pm.ActivityInfo;
74import android.content.pm.ApplicationInfo;
75import android.content.pm.ConfigurationInfo;
76import android.content.pm.IPackageDataObserver;
77import android.content.pm.IPackageManager;
78import android.content.pm.InstrumentationInfo;
79import android.content.pm.PackageInfo;
80import android.content.pm.PackageManager;
81import android.content.pm.UserInfo;
82import android.content.pm.PackageManager.NameNotFoundException;
83import android.content.pm.PathPermission;
84import android.content.pm.ProviderInfo;
85import android.content.pm.ResolveInfo;
86import android.content.pm.ServiceInfo;
87import android.content.res.CompatibilityInfo;
88import android.content.res.Configuration;
89import android.graphics.Bitmap;
90import android.net.Proxy;
91import android.net.ProxyProperties;
92import android.net.Uri;
93import android.os.Binder;
94import android.os.Build;
95import android.os.Bundle;
96import android.os.Debug;
97import android.os.DropBoxManager;
98import android.os.Environment;
99import android.os.FileObserver;
100import android.os.FileUtils;
101import android.os.Handler;
102import android.os.IBinder;
103import android.os.IPermissionController;
104import android.os.IRemoteCallback;
105import android.os.IUserManager;
106import android.os.Looper;
107import android.os.Message;
108import android.os.Parcel;
109import android.os.ParcelFileDescriptor;
110import android.os.Process;
111import android.os.RemoteCallbackList;
112import android.os.RemoteException;
113import android.os.SELinux;
114import android.os.ServiceManager;
115import android.os.StrictMode;
116import android.os.SystemClock;
117import android.os.SystemProperties;
118import android.os.UserHandle;
119import android.provider.Settings;
120import android.text.format.Time;
121import android.util.EventLog;
122import android.util.Log;
123import android.util.Pair;
124import android.util.PrintWriterPrinter;
125import android.util.Slog;
126import android.util.SparseArray;
127import android.util.TimeUtils;
128import android.view.Gravity;
129import android.view.LayoutInflater;
130import android.view.View;
131import android.view.WindowManager;
132import android.view.WindowManagerPolicy;
133
134import java.io.BufferedInputStream;
135import java.io.BufferedOutputStream;
136import java.io.BufferedReader;
137import java.io.DataInputStream;
138import java.io.DataOutputStream;
139import java.io.File;
140import java.io.FileDescriptor;
141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
143import java.io.FileOutputStream;
144import java.io.IOException;
145import java.io.InputStreamReader;
146import java.io.PrintWriter;
147import java.io.StringWriter;
148import java.lang.ref.WeakReference;
149import java.util.ArrayList;
150import java.util.Collections;
151import java.util.Comparator;
152import java.util.HashMap;
153import java.util.HashSet;
154import java.util.Iterator;
155import java.util.List;
156import java.util.Locale;
157import java.util.Map;
158import java.util.Set;
159import java.util.concurrent.atomic.AtomicBoolean;
160import java.util.concurrent.atomic.AtomicLong;
161
162public final class ActivityManagerService extends ActivityManagerNative
163        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
164    private static final String USER_DATA_DIR = "/data/user/";
165    static final String TAG = "ActivityManager";
166    static final String TAG_MU = "ActivityManagerServiceMU";
167    static final boolean DEBUG = false;
168    static final boolean localLOGV = DEBUG;
169    static final boolean DEBUG_SWITCH = localLOGV || false;
170    static final boolean DEBUG_TASKS = localLOGV || false;
171    static final boolean DEBUG_PAUSE = localLOGV || false;
172    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
173    static final boolean DEBUG_TRANSITION = localLOGV || false;
174    static final boolean DEBUG_BROADCAST = localLOGV || false;
175    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
177    static final boolean DEBUG_SERVICE = localLOGV || false;
178    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
179    static final boolean DEBUG_VISBILITY = localLOGV || false;
180    static final boolean DEBUG_PROCESSES = localLOGV || false;
181    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
182    static final boolean DEBUG_PROVIDER = localLOGV || false;
183    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
184    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
185    static final boolean DEBUG_RESULTS = localLOGV || false;
186    static final boolean DEBUG_BACKUP = localLOGV || false;
187    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
188    static final boolean DEBUG_POWER = localLOGV || false;
189    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
190    static final boolean DEBUG_MU = localLOGV || false;
191    static final boolean VALIDATE_TOKENS = false;
192    static final boolean SHOW_ACTIVITY_START_TIME = true;
193
194    // Control over CPU and battery monitoring.
195    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
196    static final boolean MONITOR_CPU_USAGE = true;
197    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
198    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
199    static final boolean MONITOR_THREAD_CPU_USAGE = false;
200
201    // The flags that are set for all calls we make to the package manager.
202    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
203
204    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
205
206    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
207
208    // Maximum number of recent tasks that we can remember.
209    static final int MAX_RECENT_TASKS = 20;
210
211    // Amount of time after a call to stopAppSwitches() during which we will
212    // prevent further untrusted switches from happening.
213    static final long APP_SWITCH_DELAY_TIME = 5*1000;
214
215    // How long we wait for a launched process to attach to the activity manager
216    // before we decide it's never going to come up for real.
217    static final int PROC_START_TIMEOUT = 10*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, when the process was
221    // started with a wrapper for instrumentation (such as Valgrind) because it
222    // could take much longer than usual.
223    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
224
225    // How long to wait after going idle before forcing apps to GC.
226    static final int GC_TIMEOUT = 5*1000;
227
228    // The minimum amount of time between successive GC requests for a process.
229    static final int GC_MIN_INTERVAL = 60*1000;
230
231    // The rate at which we check for apps using excessive power -- 15 mins.
232    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
233
234    // The minimum sample duration we will allow before deciding we have
235    // enough data on wake locks to start killing things.
236    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on CPU usage to start killing things.
240    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // How long we allow a receiver to run before giving up on it.
243    static final int BROADCAST_FG_TIMEOUT = 10*1000;
244    static final int BROADCAST_BG_TIMEOUT = 60*1000;
245
246    // How long we wait until we timeout on key dispatching.
247    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
248
249    // How long we wait until we timeout on key dispatching during instrumentation.
250    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
251
252    // Amount of time we wait for observers to handle a user switch before
253    // giving up on them and unfreezing the screen.
254    static final int USER_SWITCH_TIMEOUT = 2*1000;
255
256    // Maximum number of users we allow to be running at a time.
257    static final int MAX_RUNNING_USERS = 3;
258
259    static final int MY_PID = Process.myPid();
260
261    static final String[] EMPTY_STRING_ARRAY = new String[0];
262
263    public ActivityStack mMainStack;
264
265    private final boolean mHeadless;
266
267    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
268    // default actuion automatically.  Important for devices without direct input
269    // devices.
270    private boolean mShowDialogs = true;
271
272    /**
273     * Description of a request to start a new activity, which has been held
274     * due to app switches being disabled.
275     */
276    static class PendingActivityLaunch {
277        ActivityRecord r;
278        ActivityRecord sourceRecord;
279        int startFlags;
280    }
281
282    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
283            = new ArrayList<PendingActivityLaunch>();
284
285
286    BroadcastQueue mFgBroadcastQueue;
287    BroadcastQueue mBgBroadcastQueue;
288    // Convenient for easy iteration over the queues. Foreground is first
289    // so that dispatch of foreground broadcasts gets precedence.
290    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
291
292    BroadcastQueue broadcastQueueForIntent(Intent intent) {
293        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
294        if (DEBUG_BACKGROUND_BROADCAST) {
295            Slog.i(TAG, "Broadcast intent " + intent + " on "
296                    + (isFg ? "foreground" : "background")
297                    + " queue");
298        }
299        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
300    }
301
302    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
303        for (BroadcastQueue queue : mBroadcastQueues) {
304            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
305            if (r != null) {
306                return r;
307            }
308        }
309        return null;
310    }
311
312    /**
313     * Activity we have told the window manager to have key focus.
314     */
315    ActivityRecord mFocusedActivity = null;
316    /**
317     * List of intents that were used to start the most recent tasks.
318     */
319    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
320
321    /**
322     * Process management.
323     */
324    final ProcessList mProcessList = new ProcessList();
325
326    /**
327     * All of the applications we currently have running organized by name.
328     * The keys are strings of the application package name (as
329     * returned by the package manager), and the keys are ApplicationRecord
330     * objects.
331     */
332    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
333
334    /**
335     * The currently running isolated processes.
336     */
337    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
338
339    /**
340     * Counter for assigning isolated process uids, to avoid frequently reusing the
341     * same ones.
342     */
343    int mNextIsolatedProcessUid = 0;
344
345    /**
346     * The currently running heavy-weight process, if any.
347     */
348    ProcessRecord mHeavyWeightProcess = null;
349
350    /**
351     * The last time that various processes have crashed.
352     */
353    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
354
355    /**
356     * Set of applications that we consider to be bad, and will reject
357     * incoming broadcasts from (which the user has no control over).
358     * Processes are added to this set when they have crashed twice within
359     * a minimum amount of time; they are removed from it when they are
360     * later restarted (hopefully due to some user action).  The value is the
361     * time it was added to the list.
362     */
363    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
364
365    /**
366     * All of the processes we currently have running organized by pid.
367     * The keys are the pid running the application.
368     *
369     * <p>NOTE: This object is protected by its own lock, NOT the global
370     * activity manager lock!
371     */
372    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
373
374    /**
375     * All of the processes that have been forced to be foreground.  The key
376     * is the pid of the caller who requested it (we hold a death
377     * link on it).
378     */
379    abstract class ForegroundToken implements IBinder.DeathRecipient {
380        int pid;
381        IBinder token;
382    }
383    final SparseArray<ForegroundToken> mForegroundProcesses
384            = new SparseArray<ForegroundToken>();
385
386    /**
387     * List of records for processes that someone had tried to start before the
388     * system was ready.  We don't start them at that point, but ensure they
389     * are started by the time booting is complete.
390     */
391    final ArrayList<ProcessRecord> mProcessesOnHold
392            = new ArrayList<ProcessRecord>();
393
394    /**
395     * List of persistent applications that are in the process
396     * of being started.
397     */
398    final ArrayList<ProcessRecord> mPersistentStartingProcesses
399            = new ArrayList<ProcessRecord>();
400
401    /**
402     * Processes that are being forcibly torn down.
403     */
404    final ArrayList<ProcessRecord> mRemovedProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of running applications, sorted by recent usage.
409     * The first entry in the list is the least recently used.
410     * It contains ApplicationRecord objects.  This list does NOT include
411     * any persistent application records (since we never want to exit them).
412     */
413    final ArrayList<ProcessRecord> mLruProcesses
414            = new ArrayList<ProcessRecord>();
415
416    /**
417     * List of processes that should gc as soon as things are idle.
418     */
419    final ArrayList<ProcessRecord> mProcessesToGc
420            = new ArrayList<ProcessRecord>();
421
422    /**
423     * This is the process holding what we currently consider to be
424     * the "home" activity.
425     */
426    ProcessRecord mHomeProcess;
427
428    /**
429     * This is the process holding the activity the user last visited that
430     * is in a different process from the one they are currently in.
431     */
432    ProcessRecord mPreviousProcess;
433
434    /**
435     * The time at which the previous process was last visible.
436     */
437    long mPreviousProcessVisibleTime;
438
439    /**
440     * Which uses have been started, so are allowed to run code.
441     */
442    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
443
444    /**
445     * LRU list of history of current users.  Most recently current is at the end.
446     */
447    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
448
449    /**
450     * Registered observers of the user switching mechanics.
451     */
452    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
453            = new RemoteCallbackList<IUserSwitchObserver>();
454
455    /**
456     * Currently active user switch.
457     */
458    Object mCurUserSwitchCallback;
459
460    /**
461     * Packages that the user has asked to have run in screen size
462     * compatibility mode instead of filling the screen.
463     */
464    final CompatModePackages mCompatModePackages;
465
466    /**
467     * Set of PendingResultRecord objects that are currently active.
468     */
469    final HashSet mPendingResultRecords = new HashSet();
470
471    /**
472     * Set of IntentSenderRecord objects that are currently active.
473     */
474    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
475            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
476
477    /**
478     * Fingerprints (hashCode()) of stack traces that we've
479     * already logged DropBox entries for.  Guarded by itself.  If
480     * something (rogue user app) forces this over
481     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
482     */
483    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
484    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
485
486    /**
487     * Strict Mode background batched logging state.
488     *
489     * The string buffer is guarded by itself, and its lock is also
490     * used to determine if another batched write is already
491     * in-flight.
492     */
493    private final StringBuilder mStrictModeBuffer = new StringBuilder();
494
495    /**
496     * Keeps track of all IIntentReceivers that have been registered for
497     * broadcasts.  Hash keys are the receiver IBinder, hash value is
498     * a ReceiverList.
499     */
500    final HashMap mRegisteredReceivers = new HashMap();
501
502    /**
503     * Resolver for broadcast intents to registered receivers.
504     * Holds BroadcastFilter (subclass of IntentFilter).
505     */
506    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
507            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
508        @Override
509        protected boolean allowFilterResult(
510                BroadcastFilter filter, List<BroadcastFilter> dest) {
511            IBinder target = filter.receiverList.receiver.asBinder();
512            for (int i=dest.size()-1; i>=0; i--) {
513                if (dest.get(i).receiverList.receiver.asBinder() == target) {
514                    return false;
515                }
516            }
517            return true;
518        }
519
520        @Override
521        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
522            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
523                    || userId == filter.owningUserId) {
524                return super.newResult(filter, match, userId);
525            }
526            return null;
527        }
528
529        @Override
530        protected BroadcastFilter[] newArray(int size) {
531            return new BroadcastFilter[size];
532        }
533
534        @Override
535        protected String packageForFilter(BroadcastFilter filter) {
536            return filter.packageName;
537        }
538    };
539
540    /**
541     * State of all active sticky broadcasts per user.  Keys are the action of the
542     * sticky Intent, values are an ArrayList of all broadcasted intents with
543     * that action (which should usually be one).  The SparseArray is keyed
544     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
545     * for stickies that are sent to all users.
546     */
547    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
548            new SparseArray<HashMap<String, ArrayList<Intent>>>();
549
550    final ActiveServices mServices;
551
552    /**
553     * Backup/restore process management
554     */
555    String mBackupAppName = null;
556    BackupRecord mBackupTarget = null;
557
558    /**
559     * List of PendingThumbnailsRecord objects of clients who are still
560     * waiting to receive all of the thumbnails for a task.
561     */
562    final ArrayList mPendingThumbnails = new ArrayList();
563
564    /**
565     * List of HistoryRecord objects that have been finished and must
566     * still report back to a pending thumbnail receiver.
567     */
568    final ArrayList mCancelledThumbnails = new ArrayList();
569
570    final ProviderMap mProviderMap;
571
572    /**
573     * List of content providers who have clients waiting for them.  The
574     * application is currently being launched and the provider will be
575     * removed from this list once it is published.
576     */
577    final ArrayList<ContentProviderRecord> mLaunchingProviders
578            = new ArrayList<ContentProviderRecord>();
579
580    /**
581     * Global set of specific Uri permissions that have been granted.
582     */
583    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
584            = new SparseArray<HashMap<Uri, UriPermission>>();
585
586    CoreSettingsObserver mCoreSettingsObserver;
587
588    /**
589     * Thread-local storage used to carry caller permissions over through
590     * indirect content-provider access.
591     * @see #ActivityManagerService.openContentUri()
592     */
593    private class Identity {
594        public int pid;
595        public int uid;
596
597        Identity(int _pid, int _uid) {
598            pid = _pid;
599            uid = _uid;
600        }
601    }
602
603    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
604
605    /**
606     * All information we have collected about the runtime performance of
607     * any user id that can impact battery performance.
608     */
609    final BatteryStatsService mBatteryStatsService;
610
611    /**
612     * information about component usage
613     */
614    final UsageStatsService mUsageStatsService;
615
616    /**
617     * Current configuration information.  HistoryRecord objects are given
618     * a reference to this object to indicate which configuration they are
619     * currently running in, so this object must be kept immutable.
620     */
621    Configuration mConfiguration = new Configuration();
622
623    /**
624     * Current sequencing integer of the configuration, for skipping old
625     * configurations.
626     */
627    int mConfigurationSeq = 0;
628
629    /**
630     * Hardware-reported OpenGLES version.
631     */
632    final int GL_ES_VERSION;
633
634    /**
635     * List of initialization arguments to pass to all processes when binding applications to them.
636     * For example, references to the commonly used services.
637     */
638    HashMap<String, IBinder> mAppBindArgs;
639
640    /**
641     * Temporary to avoid allocations.  Protected by main lock.
642     */
643    final StringBuilder mStringBuilder = new StringBuilder(256);
644
645    /**
646     * Used to control how we initialize the service.
647     */
648    boolean mStartRunning = false;
649    ComponentName mTopComponent;
650    String mTopAction;
651    String mTopData;
652    boolean mProcessesReady = false;
653    boolean mSystemReady = false;
654    boolean mBooting = false;
655    boolean mWaitingUpdate = false;
656    boolean mDidUpdate = false;
657    boolean mOnBattery = false;
658    boolean mLaunchWarningShown = false;
659
660    Context mContext;
661
662    int mFactoryTest;
663
664    boolean mCheckedForSetup;
665
666    /**
667     * The time at which we will allow normal application switches again,
668     * after a call to {@link #stopAppSwitches()}.
669     */
670    long mAppSwitchesAllowedTime;
671
672    /**
673     * This is set to true after the first switch after mAppSwitchesAllowedTime
674     * is set; any switches after that will clear the time.
675     */
676    boolean mDidAppSwitch;
677
678    /**
679     * Last time (in realtime) at which we checked for power usage.
680     */
681    long mLastPowerCheckRealtime;
682
683    /**
684     * Last time (in uptime) at which we checked for power usage.
685     */
686    long mLastPowerCheckUptime;
687
688    /**
689     * Set while we are wanting to sleep, to prevent any
690     * activities from being started/resumed.
691     */
692    boolean mSleeping = false;
693
694    /**
695     * State of external calls telling us if the device is asleep.
696     */
697    boolean mWentToSleep = false;
698
699    /**
700     * State of external call telling us if the lock screen is shown.
701     */
702    boolean mLockScreenShown = false;
703
704    /**
705     * Set if we are shutting down the system, similar to sleeping.
706     */
707    boolean mShuttingDown = false;
708
709    /**
710     * Task identifier that activities are currently being started
711     * in.  Incremented each time a new task is created.
712     * todo: Replace this with a TokenSpace class that generates non-repeating
713     * integers that won't wrap.
714     */
715    int mCurTask = 1;
716
717    /**
718     * Current sequence id for oom_adj computation traversal.
719     */
720    int mAdjSeq = 0;
721
722    /**
723     * Current sequence id for process LRU updating.
724     */
725    int mLruSeq = 0;
726
727    /**
728     * Keep track of the non-hidden/empty process we last found, to help
729     * determine how to distribute hidden/empty processes next time.
730     */
731    int mNumNonHiddenProcs = 0;
732
733    /**
734     * Keep track of the number of hidden procs, to balance oom adj
735     * distribution between those and empty procs.
736     */
737    int mNumHiddenProcs = 0;
738
739    /**
740     * Keep track of the number of service processes we last found, to
741     * determine on the next iteration which should be B services.
742     */
743    int mNumServiceProcs = 0;
744    int mNewNumServiceProcs = 0;
745
746    /**
747     * System monitoring: number of processes that died since the last
748     * N procs were started.
749     */
750    int[] mProcDeaths = new int[20];
751
752    /**
753     * This is set if we had to do a delayed dexopt of an app before launching
754     * it, to increasing the ANR timeouts in that case.
755     */
756    boolean mDidDexOpt;
757
758    String mDebugApp = null;
759    boolean mWaitForDebugger = false;
760    boolean mDebugTransient = false;
761    String mOrigDebugApp = null;
762    boolean mOrigWaitForDebugger = false;
763    boolean mAlwaysFinishActivities = false;
764    IActivityController mController = null;
765    String mProfileApp = null;
766    ProcessRecord mProfileProc = null;
767    String mProfileFile;
768    ParcelFileDescriptor mProfileFd;
769    int mProfileType = 0;
770    boolean mAutoStopProfiler = false;
771    String mOpenGlTraceApp = null;
772
773    static class ProcessChangeItem {
774        static final int CHANGE_ACTIVITIES = 1<<0;
775        static final int CHANGE_IMPORTANCE= 1<<1;
776        int changes;
777        int uid;
778        int pid;
779        int importance;
780        boolean foregroundActivities;
781    }
782
783    final RemoteCallbackList<IProcessObserver> mProcessObservers
784            = new RemoteCallbackList<IProcessObserver>();
785    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
786
787    final ArrayList<ProcessChangeItem> mPendingProcessChanges
788            = new ArrayList<ProcessChangeItem>();
789    final ArrayList<ProcessChangeItem> mAvailProcessChanges
790            = new ArrayList<ProcessChangeItem>();
791
792    /**
793     * Callback of last caller to {@link #requestPss}.
794     */
795    Runnable mRequestPssCallback;
796
797    /**
798     * Remaining processes for which we are waiting results from the last
799     * call to {@link #requestPss}.
800     */
801    final ArrayList<ProcessRecord> mRequestPssList
802            = new ArrayList<ProcessRecord>();
803
804    /**
805     * Runtime statistics collection thread.  This object's lock is used to
806     * protect all related state.
807     */
808    final Thread mProcessStatsThread;
809
810    /**
811     * Used to collect process stats when showing not responding dialog.
812     * Protected by mProcessStatsThread.
813     */
814    final ProcessStats mProcessStats = new ProcessStats(
815            MONITOR_THREAD_CPU_USAGE);
816    final AtomicLong mLastCpuTime = new AtomicLong(0);
817    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
818
819    long mLastWriteTime = 0;
820
821    /**
822     * Set to true after the system has finished booting.
823     */
824    boolean mBooted = false;
825
826    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
827    int mProcessLimitOverride = -1;
828
829    WindowManagerService mWindowManager;
830
831    static ActivityManagerService mSelf;
832    static ActivityThread mSystemThread;
833
834    private int mCurrentUserId;
835    private UserManagerService mUserManager;
836
837    private final class AppDeathRecipient implements IBinder.DeathRecipient {
838        final ProcessRecord mApp;
839        final int mPid;
840        final IApplicationThread mAppThread;
841
842        AppDeathRecipient(ProcessRecord app, int pid,
843                IApplicationThread thread) {
844            if (localLOGV) Slog.v(
845                TAG, "New death recipient " + this
846                + " for thread " + thread.asBinder());
847            mApp = app;
848            mPid = pid;
849            mAppThread = thread;
850        }
851
852        public void binderDied() {
853            if (localLOGV) Slog.v(
854                TAG, "Death received in " + this
855                + " for thread " + mAppThread.asBinder());
856            synchronized(ActivityManagerService.this) {
857                appDiedLocked(mApp, mPid, mAppThread);
858            }
859        }
860    }
861
862    static final int SHOW_ERROR_MSG = 1;
863    static final int SHOW_NOT_RESPONDING_MSG = 2;
864    static final int SHOW_FACTORY_ERROR_MSG = 3;
865    static final int UPDATE_CONFIGURATION_MSG = 4;
866    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
867    static final int WAIT_FOR_DEBUGGER_MSG = 6;
868    static final int SERVICE_TIMEOUT_MSG = 12;
869    static final int UPDATE_TIME_ZONE = 13;
870    static final int SHOW_UID_ERROR_MSG = 14;
871    static final int IM_FEELING_LUCKY_MSG = 15;
872    static final int PROC_START_TIMEOUT_MSG = 20;
873    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
874    static final int KILL_APPLICATION_MSG = 22;
875    static final int FINALIZE_PENDING_INTENT_MSG = 23;
876    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
877    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
878    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
879    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
880    static final int CLEAR_DNS_CACHE = 28;
881    static final int UPDATE_HTTP_PROXY = 29;
882    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
883    static final int DISPATCH_PROCESSES_CHANGED = 31;
884    static final int DISPATCH_PROCESS_DIED = 32;
885    static final int REPORT_MEM_USAGE = 33;
886    static final int REPORT_USER_SWITCH_MSG = 34;
887    static final int CONTINUE_USER_SWITCH_MSG = 35;
888    static final int USER_SWITCH_TIMEOUT_MSG = 36;
889
890    static final int FIRST_ACTIVITY_STACK_MSG = 100;
891    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
892    static final int FIRST_COMPAT_MODE_MSG = 300;
893
894    AlertDialog mUidAlert;
895    CompatModeDialog mCompatModeDialog;
896    long mLastMemUsageReportTime = 0;
897
898    final Handler mHandler = new Handler() {
899        //public Handler() {
900        //    if (localLOGV) Slog.v(TAG, "Handler started!");
901        //}
902
903        public void handleMessage(Message msg) {
904            switch (msg.what) {
905            case SHOW_ERROR_MSG: {
906                HashMap data = (HashMap) msg.obj;
907                synchronized (ActivityManagerService.this) {
908                    ProcessRecord proc = (ProcessRecord)data.get("app");
909                    if (proc != null && proc.crashDialog != null) {
910                        Slog.e(TAG, "App already has crash dialog: " + proc);
911                        return;
912                    }
913                    AppErrorResult res = (AppErrorResult) data.get("result");
914                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
915                        Dialog d = new AppErrorDialog(mContext, res, proc);
916                        d.show();
917                        proc.crashDialog = d;
918                    } else {
919                        // The device is asleep, so just pretend that the user
920                        // saw a crash dialog and hit "force quit".
921                        res.set(0);
922                    }
923                }
924
925                ensureBootCompleted();
926            } break;
927            case SHOW_NOT_RESPONDING_MSG: {
928                synchronized (ActivityManagerService.this) {
929                    HashMap data = (HashMap) msg.obj;
930                    ProcessRecord proc = (ProcessRecord)data.get("app");
931                    if (proc != null && proc.anrDialog != null) {
932                        Slog.e(TAG, "App already has anr dialog: " + proc);
933                        return;
934                    }
935
936                    Intent intent = new Intent("android.intent.action.ANR");
937                    if (!mProcessesReady) {
938                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
939                                | Intent.FLAG_RECEIVER_FOREGROUND);
940                    }
941                    broadcastIntentLocked(null, null, intent,
942                            null, null, 0, null, null, null,
943                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
944
945                    if (mShowDialogs) {
946                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
947                                mContext, proc, (ActivityRecord)data.get("activity"));
948                        d.show();
949                        proc.anrDialog = d;
950                    } else {
951                        // Just kill the app if there is no dialog to be shown.
952                        killAppAtUsersRequest(proc, null);
953                    }
954                }
955
956                ensureBootCompleted();
957            } break;
958            case SHOW_STRICT_MODE_VIOLATION_MSG: {
959                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
960                synchronized (ActivityManagerService.this) {
961                    ProcessRecord proc = (ProcessRecord) data.get("app");
962                    if (proc == null) {
963                        Slog.e(TAG, "App not found when showing strict mode dialog.");
964                        break;
965                    }
966                    if (proc.crashDialog != null) {
967                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
968                        return;
969                    }
970                    AppErrorResult res = (AppErrorResult) data.get("result");
971                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
972                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
973                        d.show();
974                        proc.crashDialog = d;
975                    } else {
976                        // The device is asleep, so just pretend that the user
977                        // saw a crash dialog and hit "force quit".
978                        res.set(0);
979                    }
980                }
981                ensureBootCompleted();
982            } break;
983            case SHOW_FACTORY_ERROR_MSG: {
984                Dialog d = new FactoryErrorDialog(
985                    mContext, msg.getData().getCharSequence("msg"));
986                d.show();
987                ensureBootCompleted();
988            } break;
989            case UPDATE_CONFIGURATION_MSG: {
990                final ContentResolver resolver = mContext.getContentResolver();
991                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
992            } break;
993            case GC_BACKGROUND_PROCESSES_MSG: {
994                synchronized (ActivityManagerService.this) {
995                    performAppGcsIfAppropriateLocked();
996                }
997            } break;
998            case WAIT_FOR_DEBUGGER_MSG: {
999                synchronized (ActivityManagerService.this) {
1000                    ProcessRecord app = (ProcessRecord)msg.obj;
1001                    if (msg.arg1 != 0) {
1002                        if (!app.waitedForDebugger) {
1003                            Dialog d = new AppWaitingForDebuggerDialog(
1004                                    ActivityManagerService.this,
1005                                    mContext, app);
1006                            app.waitDialog = d;
1007                            app.waitedForDebugger = true;
1008                            d.show();
1009                        }
1010                    } else {
1011                        if (app.waitDialog != null) {
1012                            app.waitDialog.dismiss();
1013                            app.waitDialog = null;
1014                        }
1015                    }
1016                }
1017            } break;
1018            case SERVICE_TIMEOUT_MSG: {
1019                if (mDidDexOpt) {
1020                    mDidDexOpt = false;
1021                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1022                    nmsg.obj = msg.obj;
1023                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1024                    return;
1025                }
1026                mServices.serviceTimeout((ProcessRecord)msg.obj);
1027            } break;
1028            case UPDATE_TIME_ZONE: {
1029                synchronized (ActivityManagerService.this) {
1030                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1031                        ProcessRecord r = mLruProcesses.get(i);
1032                        if (r.thread != null) {
1033                            try {
1034                                r.thread.updateTimeZone();
1035                            } catch (RemoteException ex) {
1036                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1037                            }
1038                        }
1039                    }
1040                }
1041            } break;
1042            case CLEAR_DNS_CACHE: {
1043                synchronized (ActivityManagerService.this) {
1044                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1045                        ProcessRecord r = mLruProcesses.get(i);
1046                        if (r.thread != null) {
1047                            try {
1048                                r.thread.clearDnsCache();
1049                            } catch (RemoteException ex) {
1050                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1051                            }
1052                        }
1053                    }
1054                }
1055            } break;
1056            case UPDATE_HTTP_PROXY: {
1057                ProxyProperties proxy = (ProxyProperties)msg.obj;
1058                String host = "";
1059                String port = "";
1060                String exclList = "";
1061                if (proxy != null) {
1062                    host = proxy.getHost();
1063                    port = Integer.toString(proxy.getPort());
1064                    exclList = proxy.getExclusionList();
1065                }
1066                synchronized (ActivityManagerService.this) {
1067                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1068                        ProcessRecord r = mLruProcesses.get(i);
1069                        if (r.thread != null) {
1070                            try {
1071                                r.thread.setHttpProxy(host, port, exclList);
1072                            } catch (RemoteException ex) {
1073                                Slog.w(TAG, "Failed to update http proxy for: " +
1074                                        r.info.processName);
1075                            }
1076                        }
1077                    }
1078                }
1079            } break;
1080            case SHOW_UID_ERROR_MSG: {
1081                String title = "System UIDs Inconsistent";
1082                String text = "UIDs on the system are inconsistent, you need to wipe your"
1083                        + " data partition or your device will be unstable.";
1084                Log.e(TAG, title + ": " + text);
1085                if (mShowDialogs) {
1086                    // XXX This is a temporary dialog, no need to localize.
1087                    AlertDialog d = new BaseErrorDialog(mContext);
1088                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1089                    d.setCancelable(false);
1090                    d.setTitle(title);
1091                    d.setMessage(text);
1092                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1093                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1094                    mUidAlert = d;
1095                    d.show();
1096                }
1097            } break;
1098            case IM_FEELING_LUCKY_MSG: {
1099                if (mUidAlert != null) {
1100                    mUidAlert.dismiss();
1101                    mUidAlert = null;
1102                }
1103            } break;
1104            case PROC_START_TIMEOUT_MSG: {
1105                if (mDidDexOpt) {
1106                    mDidDexOpt = false;
1107                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1108                    nmsg.obj = msg.obj;
1109                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1110                    return;
1111                }
1112                ProcessRecord app = (ProcessRecord)msg.obj;
1113                synchronized (ActivityManagerService.this) {
1114                    processStartTimedOutLocked(app);
1115                }
1116            } break;
1117            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1118                synchronized (ActivityManagerService.this) {
1119                    doPendingActivityLaunchesLocked(true);
1120                }
1121            } break;
1122            case KILL_APPLICATION_MSG: {
1123                synchronized (ActivityManagerService.this) {
1124                    int appid = msg.arg1;
1125                    boolean restart = (msg.arg2 == 1);
1126                    String pkg = (String) msg.obj;
1127                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1128                            UserHandle.USER_ALL);
1129                }
1130            } break;
1131            case FINALIZE_PENDING_INTENT_MSG: {
1132                ((PendingIntentRecord)msg.obj).completeFinalize();
1133            } break;
1134            case POST_HEAVY_NOTIFICATION_MSG: {
1135                INotificationManager inm = NotificationManager.getService();
1136                if (inm == null) {
1137                    return;
1138                }
1139
1140                ActivityRecord root = (ActivityRecord)msg.obj;
1141                ProcessRecord process = root.app;
1142                if (process == null) {
1143                    return;
1144                }
1145
1146                try {
1147                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1148                    String text = mContext.getString(R.string.heavy_weight_notification,
1149                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1150                    Notification notification = new Notification();
1151                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1152                    notification.when = 0;
1153                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1154                    notification.tickerText = text;
1155                    notification.defaults = 0; // please be quiet
1156                    notification.sound = null;
1157                    notification.vibrate = null;
1158                    notification.setLatestEventInfo(context, text,
1159                            mContext.getText(R.string.heavy_weight_notification_detail),
1160                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1161                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1162                                    new UserHandle(root.userId)));
1163
1164                    try {
1165                        int[] outId = new int[1];
1166                        inm.enqueueNotificationWithTag("android", null,
1167                                R.string.heavy_weight_notification,
1168                                notification, outId, root.userId);
1169                    } catch (RuntimeException e) {
1170                        Slog.w(ActivityManagerService.TAG,
1171                                "Error showing notification for heavy-weight app", e);
1172                    } catch (RemoteException e) {
1173                    }
1174                } catch (NameNotFoundException e) {
1175                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1176                }
1177            } break;
1178            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1179                INotificationManager inm = NotificationManager.getService();
1180                if (inm == null) {
1181                    return;
1182                }
1183                try {
1184                    inm.cancelNotificationWithTag("android", null,
1185                            R.string.heavy_weight_notification,  msg.arg1);
1186                } catch (RuntimeException e) {
1187                    Slog.w(ActivityManagerService.TAG,
1188                            "Error canceling notification for service", e);
1189                } catch (RemoteException e) {
1190                }
1191            } break;
1192            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1193                synchronized (ActivityManagerService.this) {
1194                    checkExcessivePowerUsageLocked(true);
1195                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1196                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1197                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1198                }
1199            } break;
1200            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    ActivityRecord ar = (ActivityRecord)msg.obj;
1203                    if (mCompatModeDialog != null) {
1204                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1205                                ar.info.applicationInfo.packageName)) {
1206                            return;
1207                        }
1208                        mCompatModeDialog.dismiss();
1209                        mCompatModeDialog = null;
1210                    }
1211                    if (ar != null && false) {
1212                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1213                                ar.packageName)) {
1214                            int mode = mCompatModePackages.computeCompatModeLocked(
1215                                    ar.info.applicationInfo);
1216                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1217                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1218                                mCompatModeDialog = new CompatModeDialog(
1219                                        ActivityManagerService.this, mContext,
1220                                        ar.info.applicationInfo);
1221                                mCompatModeDialog.show();
1222                            }
1223                        }
1224                    }
1225                }
1226                break;
1227            }
1228            case DISPATCH_PROCESSES_CHANGED: {
1229                dispatchProcessesChanged();
1230                break;
1231            }
1232            case DISPATCH_PROCESS_DIED: {
1233                final int pid = msg.arg1;
1234                final int uid = msg.arg2;
1235                dispatchProcessDied(pid, uid);
1236                break;
1237            }
1238            case REPORT_MEM_USAGE: {
1239                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1240                if (!isDebuggable) {
1241                    return;
1242                }
1243                synchronized (ActivityManagerService.this) {
1244                    long now = SystemClock.uptimeMillis();
1245                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1246                        // Don't report more than every 5 minutes to somewhat
1247                        // avoid spamming.
1248                        return;
1249                    }
1250                    mLastMemUsageReportTime = now;
1251                }
1252                Thread thread = new Thread() {
1253                    @Override public void run() {
1254                        StringBuilder dropBuilder = new StringBuilder(1024);
1255                        StringBuilder logBuilder = new StringBuilder(1024);
1256                        StringWriter oomSw = new StringWriter();
1257                        PrintWriter oomPw = new PrintWriter(oomSw);
1258                        StringWriter catSw = new StringWriter();
1259                        PrintWriter catPw = new PrintWriter(catSw);
1260                        String[] emptyArgs = new String[] { };
1261                        StringBuilder tag = new StringBuilder(128);
1262                        StringBuilder stack = new StringBuilder(128);
1263                        tag.append("Low on memory -- ");
1264                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1265                                tag, stack);
1266                        dropBuilder.append(stack);
1267                        dropBuilder.append('\n');
1268                        dropBuilder.append('\n');
1269                        String oomString = oomSw.toString();
1270                        dropBuilder.append(oomString);
1271                        dropBuilder.append('\n');
1272                        logBuilder.append(oomString);
1273                        try {
1274                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1275                                    "procrank", });
1276                            final InputStreamReader converter = new InputStreamReader(
1277                                    proc.getInputStream());
1278                            BufferedReader in = new BufferedReader(converter);
1279                            String line;
1280                            while (true) {
1281                                line = in.readLine();
1282                                if (line == null) {
1283                                    break;
1284                                }
1285                                if (line.length() > 0) {
1286                                    logBuilder.append(line);
1287                                    logBuilder.append('\n');
1288                                }
1289                                dropBuilder.append(line);
1290                                dropBuilder.append('\n');
1291                            }
1292                            converter.close();
1293                        } catch (IOException e) {
1294                        }
1295                        synchronized (ActivityManagerService.this) {
1296                            catPw.println();
1297                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1298                            catPw.println();
1299                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1300                                    false, false, null);
1301                            catPw.println();
1302                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1303                        }
1304                        dropBuilder.append(catSw.toString());
1305                        addErrorToDropBox("lowmem", null, "system_server", null,
1306                                null, tag.toString(), dropBuilder.toString(), null, null);
1307                        Slog.i(TAG, logBuilder.toString());
1308                        synchronized (ActivityManagerService.this) {
1309                            long now = SystemClock.uptimeMillis();
1310                            if (mLastMemUsageReportTime < now) {
1311                                mLastMemUsageReportTime = now;
1312                            }
1313                        }
1314                    }
1315                };
1316                thread.start();
1317                break;
1318            }
1319            case REPORT_USER_SWITCH_MSG: {
1320                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1321                break;
1322            }
1323            case CONTINUE_USER_SWITCH_MSG: {
1324                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1325                break;
1326            }
1327            case USER_SWITCH_TIMEOUT_MSG: {
1328                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1329                break;
1330            }
1331            }
1332        }
1333    };
1334
1335    public static void setSystemProcess() {
1336        try {
1337            ActivityManagerService m = mSelf;
1338
1339            ServiceManager.addService("activity", m, true);
1340            ServiceManager.addService("meminfo", new MemBinder(m));
1341            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1342            ServiceManager.addService("dbinfo", new DbBinder(m));
1343            if (MONITOR_CPU_USAGE) {
1344                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1345            }
1346            ServiceManager.addService("permission", new PermissionController(m));
1347
1348            ApplicationInfo info =
1349                mSelf.mContext.getPackageManager().getApplicationInfo(
1350                            "android", STOCK_PM_FLAGS);
1351            mSystemThread.installSystemApplicationInfo(info);
1352
1353            synchronized (mSelf) {
1354                ProcessRecord app = mSelf.newProcessRecordLocked(
1355                        mSystemThread.getApplicationThread(), info,
1356                        info.processName, false);
1357                app.persistent = true;
1358                app.pid = MY_PID;
1359                app.maxAdj = ProcessList.SYSTEM_ADJ;
1360                mSelf.mProcessNames.put(app.processName, app.uid, app);
1361                synchronized (mSelf.mPidsSelfLocked) {
1362                    mSelf.mPidsSelfLocked.put(app.pid, app);
1363                }
1364                mSelf.updateLruProcessLocked(app, true, true);
1365            }
1366        } catch (PackageManager.NameNotFoundException e) {
1367            throw new RuntimeException(
1368                    "Unable to find android system package", e);
1369        }
1370    }
1371
1372    public void setWindowManager(WindowManagerService wm) {
1373        mWindowManager = wm;
1374    }
1375
1376    public static final Context main(int factoryTest) {
1377        AThread thr = new AThread();
1378        thr.start();
1379
1380        synchronized (thr) {
1381            while (thr.mService == null) {
1382                try {
1383                    thr.wait();
1384                } catch (InterruptedException e) {
1385                }
1386            }
1387        }
1388
1389        ActivityManagerService m = thr.mService;
1390        mSelf = m;
1391        ActivityThread at = ActivityThread.systemMain();
1392        mSystemThread = at;
1393        Context context = at.getSystemContext();
1394        context.setTheme(android.R.style.Theme_Holo);
1395        m.mContext = context;
1396        m.mFactoryTest = factoryTest;
1397        m.mMainStack = new ActivityStack(m, context, true);
1398
1399        m.mBatteryStatsService.publish(context);
1400        m.mUsageStatsService.publish(context);
1401
1402        synchronized (thr) {
1403            thr.mReady = true;
1404            thr.notifyAll();
1405        }
1406
1407        m.startRunning(null, null, null, null);
1408
1409        return context;
1410    }
1411
1412    public static ActivityManagerService self() {
1413        return mSelf;
1414    }
1415
1416    static class AThread extends Thread {
1417        ActivityManagerService mService;
1418        boolean mReady = false;
1419
1420        public AThread() {
1421            super("ActivityManager");
1422        }
1423
1424        public void run() {
1425            Looper.prepare();
1426
1427            android.os.Process.setThreadPriority(
1428                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1429            android.os.Process.setCanSelfBackground(false);
1430
1431            ActivityManagerService m = new ActivityManagerService();
1432
1433            synchronized (this) {
1434                mService = m;
1435                notifyAll();
1436            }
1437
1438            synchronized (this) {
1439                while (!mReady) {
1440                    try {
1441                        wait();
1442                    } catch (InterruptedException e) {
1443                    }
1444                }
1445            }
1446
1447            // For debug builds, log event loop stalls to dropbox for analysis.
1448            if (StrictMode.conditionallyEnableDebugLogging()) {
1449                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1450            }
1451
1452            Looper.loop();
1453        }
1454    }
1455
1456    static class MemBinder extends Binder {
1457        ActivityManagerService mActivityManagerService;
1458        MemBinder(ActivityManagerService activityManagerService) {
1459            mActivityManagerService = activityManagerService;
1460        }
1461
1462        @Override
1463        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1464            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1465                    != PackageManager.PERMISSION_GRANTED) {
1466                pw.println("Permission Denial: can't dump meminfo from from pid="
1467                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1468                        + " without permission " + android.Manifest.permission.DUMP);
1469                return;
1470            }
1471
1472            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1473                    false, null, null, null);
1474        }
1475    }
1476
1477    static class GraphicsBinder extends Binder {
1478        ActivityManagerService mActivityManagerService;
1479        GraphicsBinder(ActivityManagerService activityManagerService) {
1480            mActivityManagerService = activityManagerService;
1481        }
1482
1483        @Override
1484        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1485            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1486                    != PackageManager.PERMISSION_GRANTED) {
1487                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1488                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1489                        + " without permission " + android.Manifest.permission.DUMP);
1490                return;
1491            }
1492
1493            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1494        }
1495    }
1496
1497    static class DbBinder extends Binder {
1498        ActivityManagerService mActivityManagerService;
1499        DbBinder(ActivityManagerService activityManagerService) {
1500            mActivityManagerService = activityManagerService;
1501        }
1502
1503        @Override
1504        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1505            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1506                    != PackageManager.PERMISSION_GRANTED) {
1507                pw.println("Permission Denial: can't dump dbinfo from from pid="
1508                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1509                        + " without permission " + android.Manifest.permission.DUMP);
1510                return;
1511            }
1512
1513            mActivityManagerService.dumpDbInfo(fd, pw, args);
1514        }
1515    }
1516
1517    static class CpuBinder extends Binder {
1518        ActivityManagerService mActivityManagerService;
1519        CpuBinder(ActivityManagerService activityManagerService) {
1520            mActivityManagerService = activityManagerService;
1521        }
1522
1523        @Override
1524        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1525            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1526                    != PackageManager.PERMISSION_GRANTED) {
1527                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1528                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1529                        + " without permission " + android.Manifest.permission.DUMP);
1530                return;
1531            }
1532
1533            synchronized (mActivityManagerService.mProcessStatsThread) {
1534                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1535                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1536                        SystemClock.uptimeMillis()));
1537            }
1538        }
1539    }
1540
1541    private ActivityManagerService() {
1542        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1543
1544        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1545        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1546        mBroadcastQueues[0] = mFgBroadcastQueue;
1547        mBroadcastQueues[1] = mBgBroadcastQueue;
1548
1549        mServices = new ActiveServices(this);
1550        mProviderMap = new ProviderMap(this);
1551
1552        File dataDir = Environment.getDataDirectory();
1553        File systemDir = new File(dataDir, "system");
1554        systemDir.mkdirs();
1555        mBatteryStatsService = new BatteryStatsService(new File(
1556                systemDir, "batterystats.bin").toString());
1557        mBatteryStatsService.getActiveStatistics().readLocked();
1558        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1559        mOnBattery = DEBUG_POWER ? true
1560                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1561        mBatteryStatsService.getActiveStatistics().setCallback(this);
1562
1563        mUsageStatsService = new UsageStatsService(new File(
1564                systemDir, "usagestats").toString());
1565        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1566
1567        // User 0 is the first and only user that runs at boot.
1568        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1569        mUserLru.add(Integer.valueOf(0));
1570
1571        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1572            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1573
1574        mConfiguration.setToDefaults();
1575        mConfiguration.setLocale(Locale.getDefault());
1576
1577        mConfigurationSeq = mConfiguration.seq = 1;
1578        mProcessStats.init();
1579
1580        mCompatModePackages = new CompatModePackages(this, systemDir);
1581
1582        // Add ourself to the Watchdog monitors.
1583        Watchdog.getInstance().addMonitor(this);
1584
1585        mProcessStatsThread = new Thread("ProcessStats") {
1586            public void run() {
1587                while (true) {
1588                    try {
1589                        try {
1590                            synchronized(this) {
1591                                final long now = SystemClock.uptimeMillis();
1592                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1593                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1594                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1595                                //        + ", write delay=" + nextWriteDelay);
1596                                if (nextWriteDelay < nextCpuDelay) {
1597                                    nextCpuDelay = nextWriteDelay;
1598                                }
1599                                if (nextCpuDelay > 0) {
1600                                    mProcessStatsMutexFree.set(true);
1601                                    this.wait(nextCpuDelay);
1602                                }
1603                            }
1604                        } catch (InterruptedException e) {
1605                        }
1606                        updateCpuStatsNow();
1607                    } catch (Exception e) {
1608                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1609                    }
1610                }
1611            }
1612        };
1613        mProcessStatsThread.start();
1614    }
1615
1616    @Override
1617    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1618            throws RemoteException {
1619        if (code == SYSPROPS_TRANSACTION) {
1620            // We need to tell all apps about the system property change.
1621            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1622            synchronized(this) {
1623                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1624                    final int NA = apps.size();
1625                    for (int ia=0; ia<NA; ia++) {
1626                        ProcessRecord app = apps.valueAt(ia);
1627                        if (app.thread != null) {
1628                            procs.add(app.thread.asBinder());
1629                        }
1630                    }
1631                }
1632            }
1633
1634            int N = procs.size();
1635            for (int i=0; i<N; i++) {
1636                Parcel data2 = Parcel.obtain();
1637                try {
1638                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1639                } catch (RemoteException e) {
1640                }
1641                data2.recycle();
1642            }
1643        }
1644        try {
1645            return super.onTransact(code, data, reply, flags);
1646        } catch (RuntimeException e) {
1647            // The activity manager only throws security exceptions, so let's
1648            // log all others.
1649            if (!(e instanceof SecurityException)) {
1650                Slog.e(TAG, "Activity Manager Crash", e);
1651            }
1652            throw e;
1653        }
1654    }
1655
1656    void updateCpuStats() {
1657        final long now = SystemClock.uptimeMillis();
1658        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1659            return;
1660        }
1661        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1662            synchronized (mProcessStatsThread) {
1663                mProcessStatsThread.notify();
1664            }
1665        }
1666    }
1667
1668    void updateCpuStatsNow() {
1669        synchronized (mProcessStatsThread) {
1670            mProcessStatsMutexFree.set(false);
1671            final long now = SystemClock.uptimeMillis();
1672            boolean haveNewCpuStats = false;
1673
1674            if (MONITOR_CPU_USAGE &&
1675                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1676                mLastCpuTime.set(now);
1677                haveNewCpuStats = true;
1678                mProcessStats.update();
1679                //Slog.i(TAG, mProcessStats.printCurrentState());
1680                //Slog.i(TAG, "Total CPU usage: "
1681                //        + mProcessStats.getTotalCpuPercent() + "%");
1682
1683                // Slog the cpu usage if the property is set.
1684                if ("true".equals(SystemProperties.get("events.cpu"))) {
1685                    int user = mProcessStats.getLastUserTime();
1686                    int system = mProcessStats.getLastSystemTime();
1687                    int iowait = mProcessStats.getLastIoWaitTime();
1688                    int irq = mProcessStats.getLastIrqTime();
1689                    int softIrq = mProcessStats.getLastSoftIrqTime();
1690                    int idle = mProcessStats.getLastIdleTime();
1691
1692                    int total = user + system + iowait + irq + softIrq + idle;
1693                    if (total == 0) total = 1;
1694
1695                    EventLog.writeEvent(EventLogTags.CPU,
1696                            ((user+system+iowait+irq+softIrq) * 100) / total,
1697                            (user * 100) / total,
1698                            (system * 100) / total,
1699                            (iowait * 100) / total,
1700                            (irq * 100) / total,
1701                            (softIrq * 100) / total);
1702                }
1703            }
1704
1705            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1706            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1707            synchronized(bstats) {
1708                synchronized(mPidsSelfLocked) {
1709                    if (haveNewCpuStats) {
1710                        if (mOnBattery) {
1711                            int perc = bstats.startAddingCpuLocked();
1712                            int totalUTime = 0;
1713                            int totalSTime = 0;
1714                            final int N = mProcessStats.countStats();
1715                            for (int i=0; i<N; i++) {
1716                                ProcessStats.Stats st = mProcessStats.getStats(i);
1717                                if (!st.working) {
1718                                    continue;
1719                                }
1720                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1721                                int otherUTime = (st.rel_utime*perc)/100;
1722                                int otherSTime = (st.rel_stime*perc)/100;
1723                                totalUTime += otherUTime;
1724                                totalSTime += otherSTime;
1725                                if (pr != null) {
1726                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1727                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1728                                            st.rel_stime-otherSTime);
1729                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1730                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1731                                } else {
1732                                    BatteryStatsImpl.Uid.Proc ps =
1733                                            bstats.getProcessStatsLocked(st.name, st.pid);
1734                                    if (ps != null) {
1735                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1736                                                st.rel_stime-otherSTime);
1737                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1738                                    }
1739                                }
1740                            }
1741                            bstats.finishAddingCpuLocked(perc, totalUTime,
1742                                    totalSTime, cpuSpeedTimes);
1743                        }
1744                    }
1745                }
1746
1747                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1748                    mLastWriteTime = now;
1749                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1750                }
1751            }
1752        }
1753    }
1754
1755    @Override
1756    public void batteryNeedsCpuUpdate() {
1757        updateCpuStatsNow();
1758    }
1759
1760    @Override
1761    public void batteryPowerChanged(boolean onBattery) {
1762        // When plugging in, update the CPU stats first before changing
1763        // the plug state.
1764        updateCpuStatsNow();
1765        synchronized (this) {
1766            synchronized(mPidsSelfLocked) {
1767                mOnBattery = DEBUG_POWER ? true : onBattery;
1768            }
1769        }
1770    }
1771
1772    /**
1773     * Initialize the application bind args. These are passed to each
1774     * process when the bindApplication() IPC is sent to the process. They're
1775     * lazily setup to make sure the services are running when they're asked for.
1776     */
1777    private HashMap<String, IBinder> getCommonServicesLocked() {
1778        if (mAppBindArgs == null) {
1779            mAppBindArgs = new HashMap<String, IBinder>();
1780
1781            // Setup the application init args
1782            mAppBindArgs.put("package", ServiceManager.getService("package"));
1783            mAppBindArgs.put("window", ServiceManager.getService("window"));
1784            mAppBindArgs.put(Context.ALARM_SERVICE,
1785                    ServiceManager.getService(Context.ALARM_SERVICE));
1786        }
1787        return mAppBindArgs;
1788    }
1789
1790    final void setFocusedActivityLocked(ActivityRecord r) {
1791        if (mFocusedActivity != r) {
1792            mFocusedActivity = r;
1793            if (r != null) {
1794                mWindowManager.setFocusedApp(r.appToken, true);
1795            }
1796        }
1797    }
1798
1799    private final void updateLruProcessInternalLocked(ProcessRecord app,
1800            boolean updateActivityTime, int bestPos) {
1801        // put it on the LRU to keep track of when it should be exited.
1802        int lrui = mLruProcesses.indexOf(app);
1803        if (lrui >= 0) mLruProcesses.remove(lrui);
1804
1805        int i = mLruProcesses.size()-1;
1806        int skipTop = 0;
1807
1808        app.lruSeq = mLruSeq;
1809
1810        // compute the new weight for this process.
1811        if (updateActivityTime) {
1812            app.lastActivityTime = SystemClock.uptimeMillis();
1813        }
1814        if (app.activities.size() > 0) {
1815            // If this process has activities, we more strongly want to keep
1816            // it around.
1817            app.lruWeight = app.lastActivityTime;
1818        } else if (app.pubProviders.size() > 0) {
1819            // If this process contains content providers, we want to keep
1820            // it a little more strongly.
1821            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1822            // Also don't let it kick out the first few "real" hidden processes.
1823            skipTop = ProcessList.MIN_HIDDEN_APPS;
1824        } else {
1825            // If this process doesn't have activities, we less strongly
1826            // want to keep it around, and generally want to avoid getting
1827            // in front of any very recently used activities.
1828            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1829            // Also don't let it kick out the first few "real" hidden processes.
1830            skipTop = ProcessList.MIN_HIDDEN_APPS;
1831        }
1832
1833        while (i >= 0) {
1834            ProcessRecord p = mLruProcesses.get(i);
1835            // If this app shouldn't be in front of the first N background
1836            // apps, then skip over that many that are currently hidden.
1837            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1838                skipTop--;
1839            }
1840            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1841                mLruProcesses.add(i+1, app);
1842                break;
1843            }
1844            i--;
1845        }
1846        if (i < 0) {
1847            mLruProcesses.add(0, app);
1848        }
1849
1850        // If the app is currently using a content provider or service,
1851        // bump those processes as well.
1852        if (app.connections.size() > 0) {
1853            for (ConnectionRecord cr : app.connections) {
1854                if (cr.binding != null && cr.binding.service != null
1855                        && cr.binding.service.app != null
1856                        && cr.binding.service.app.lruSeq != mLruSeq) {
1857                    updateLruProcessInternalLocked(cr.binding.service.app,
1858                            updateActivityTime, i+1);
1859                }
1860            }
1861        }
1862        for (int j=app.conProviders.size()-1; j>=0; j--) {
1863            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1864            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1865                updateLruProcessInternalLocked(cpr.proc,
1866                        updateActivityTime, i+1);
1867            }
1868        }
1869    }
1870
1871    final void updateLruProcessLocked(ProcessRecord app,
1872            boolean oomAdj, boolean updateActivityTime) {
1873        mLruSeq++;
1874        updateLruProcessInternalLocked(app, updateActivityTime, 0);
1875
1876        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1877        if (oomAdj) {
1878            updateOomAdjLocked();
1879        }
1880    }
1881
1882    final ProcessRecord getProcessRecordLocked(
1883            String processName, int uid) {
1884        if (uid == Process.SYSTEM_UID) {
1885            // The system gets to run in any process.  If there are multiple
1886            // processes with the same uid, just pick the first (this
1887            // should never happen).
1888            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1889                    processName);
1890            if (procs == null) return null;
1891            final int N = procs.size();
1892            for (int i = 0; i < N; i++) {
1893                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1894            }
1895        }
1896        ProcessRecord proc = mProcessNames.get(processName, uid);
1897        return proc;
1898    }
1899
1900    void ensurePackageDexOpt(String packageName) {
1901        IPackageManager pm = AppGlobals.getPackageManager();
1902        try {
1903            if (pm.performDexOpt(packageName)) {
1904                mDidDexOpt = true;
1905            }
1906        } catch (RemoteException e) {
1907        }
1908    }
1909
1910    boolean isNextTransitionForward() {
1911        int transit = mWindowManager.getPendingAppTransition();
1912        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1913                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1914                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1915    }
1916
1917    final ProcessRecord startProcessLocked(String processName,
1918            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1919            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1920            boolean isolated) {
1921        ProcessRecord app;
1922        if (!isolated) {
1923            app = getProcessRecordLocked(processName, info.uid);
1924        } else {
1925            // If this is an isolated process, it can't re-use an existing process.
1926            app = null;
1927        }
1928        // We don't have to do anything more if:
1929        // (1) There is an existing application record; and
1930        // (2) The caller doesn't think it is dead, OR there is no thread
1931        //     object attached to it so we know it couldn't have crashed; and
1932        // (3) There is a pid assigned to it, so it is either starting or
1933        //     already running.
1934        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1935                + " app=" + app + " knownToBeDead=" + knownToBeDead
1936                + " thread=" + (app != null ? app.thread : null)
1937                + " pid=" + (app != null ? app.pid : -1));
1938        if (app != null && app.pid > 0) {
1939            if (!knownToBeDead || app.thread == null) {
1940                // We already have the app running, or are waiting for it to
1941                // come up (we have a pid but not yet its thread), so keep it.
1942                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1943                // If this is a new package in the process, add the package to the list
1944                app.addPackage(info.packageName);
1945                return app;
1946            } else {
1947                // An application record is attached to a previous process,
1948                // clean it up now.
1949                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1950                handleAppDiedLocked(app, true, true);
1951            }
1952        }
1953
1954        String hostingNameStr = hostingName != null
1955                ? hostingName.flattenToShortString() : null;
1956
1957        if (!isolated) {
1958            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1959                // If we are in the background, then check to see if this process
1960                // is bad.  If so, we will just silently fail.
1961                if (mBadProcesses.get(info.processName, info.uid) != null) {
1962                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1963                            + "/" + info.processName);
1964                    return null;
1965                }
1966            } else {
1967                // When the user is explicitly starting a process, then clear its
1968                // crash count so that we won't make it bad until they see at
1969                // least one crash dialog again, and make the process good again
1970                // if it had been bad.
1971                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1972                        + "/" + info.processName);
1973                mProcessCrashTimes.remove(info.processName, info.uid);
1974                if (mBadProcesses.get(info.processName, info.uid) != null) {
1975                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1976                            info.processName);
1977                    mBadProcesses.remove(info.processName, info.uid);
1978                    if (app != null) {
1979                        app.bad = false;
1980                    }
1981                }
1982            }
1983        }
1984
1985        if (app == null) {
1986            app = newProcessRecordLocked(null, info, processName, isolated);
1987            if (app == null) {
1988                Slog.w(TAG, "Failed making new process record for "
1989                        + processName + "/" + info.uid + " isolated=" + isolated);
1990                return null;
1991            }
1992            mProcessNames.put(processName, app.uid, app);
1993            if (isolated) {
1994                mIsolatedProcesses.put(app.uid, app);
1995            }
1996        } else {
1997            // If this is a new package in the process, add the package to the list
1998            app.addPackage(info.packageName);
1999        }
2000
2001        // If the system is not ready yet, then hold off on starting this
2002        // process until it is.
2003        if (!mProcessesReady
2004                && !isAllowedWhileBooting(info)
2005                && !allowWhileBooting) {
2006            if (!mProcessesOnHold.contains(app)) {
2007                mProcessesOnHold.add(app);
2008            }
2009            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2010            return app;
2011        }
2012
2013        startProcessLocked(app, hostingType, hostingNameStr);
2014        return (app.pid != 0) ? app : null;
2015    }
2016
2017    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2018        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2019    }
2020
2021    private final void startProcessLocked(ProcessRecord app,
2022            String hostingType, String hostingNameStr) {
2023        if (app.pid > 0 && app.pid != MY_PID) {
2024            synchronized (mPidsSelfLocked) {
2025                mPidsSelfLocked.remove(app.pid);
2026                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2027            }
2028            app.setPid(0);
2029        }
2030
2031        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2032                "startProcessLocked removing on hold: " + app);
2033        mProcessesOnHold.remove(app);
2034
2035        updateCpuStats();
2036
2037        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2038        mProcDeaths[0] = 0;
2039
2040        try {
2041            int uid = app.uid;
2042
2043            int[] gids = null;
2044            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2045            if (!app.isolated) {
2046                int[] permGids = null;
2047                try {
2048                    final PackageManager pm = mContext.getPackageManager();
2049                    permGids = pm.getPackageGids(app.info.packageName);
2050
2051                    if (Environment.isExternalStorageEmulated()) {
2052                        if (pm.checkPermission(
2053                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2054                                app.info.packageName) == PERMISSION_GRANTED) {
2055                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2056                        } else {
2057                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2058                        }
2059                    }
2060                } catch (PackageManager.NameNotFoundException e) {
2061                    Slog.w(TAG, "Unable to retrieve gids", e);
2062                }
2063
2064                /*
2065                 * Add shared application GID so applications can share some
2066                 * resources like shared libraries
2067                 */
2068                if (permGids == null) {
2069                    gids = new int[1];
2070                } else {
2071                    gids = new int[permGids.length + 1];
2072                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2073                }
2074                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2075            }
2076            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2077                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2078                        && mTopComponent != null
2079                        && app.processName.equals(mTopComponent.getPackageName())) {
2080                    uid = 0;
2081                }
2082                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2083                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2084                    uid = 0;
2085                }
2086            }
2087            int debugFlags = 0;
2088            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2089                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2090                // Also turn on CheckJNI for debuggable apps. It's quite
2091                // awkward to turn on otherwise.
2092                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2093            }
2094            // Run the app in safe mode if its manifest requests so or the
2095            // system is booted in safe mode.
2096            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2097                Zygote.systemInSafeMode == true) {
2098                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2099            }
2100            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2101                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2102            }
2103            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2104                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2105            }
2106            if ("1".equals(SystemProperties.get("debug.assert"))) {
2107                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2108            }
2109
2110            // Start the process.  It will either succeed and return a result containing
2111            // the PID of the new process, or else throw a RuntimeException.
2112            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2113                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2114                    app.info.targetSdkVersion, null, null);
2115
2116            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2117            synchronized (bs) {
2118                if (bs.isOnBattery()) {
2119                    app.batteryStats.incStartsLocked();
2120                }
2121            }
2122
2123            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2124                    app.processName, hostingType,
2125                    hostingNameStr != null ? hostingNameStr : "");
2126
2127            if (app.persistent) {
2128                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2129            }
2130
2131            StringBuilder buf = mStringBuilder;
2132            buf.setLength(0);
2133            buf.append("Start proc ");
2134            buf.append(app.processName);
2135            buf.append(" for ");
2136            buf.append(hostingType);
2137            if (hostingNameStr != null) {
2138                buf.append(" ");
2139                buf.append(hostingNameStr);
2140            }
2141            buf.append(": pid=");
2142            buf.append(startResult.pid);
2143            buf.append(" uid=");
2144            buf.append(uid);
2145            buf.append(" gids={");
2146            if (gids != null) {
2147                for (int gi=0; gi<gids.length; gi++) {
2148                    if (gi != 0) buf.append(", ");
2149                    buf.append(gids[gi]);
2150
2151                }
2152            }
2153            buf.append("}");
2154            Slog.i(TAG, buf.toString());
2155            app.setPid(startResult.pid);
2156            app.usingWrapper = startResult.usingWrapper;
2157            app.removed = false;
2158            synchronized (mPidsSelfLocked) {
2159                this.mPidsSelfLocked.put(startResult.pid, app);
2160                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2161                msg.obj = app;
2162                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2163                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2164            }
2165        } catch (RuntimeException e) {
2166            // XXX do better error recovery.
2167            app.setPid(0);
2168            Slog.e(TAG, "Failure starting process " + app.processName, e);
2169        }
2170    }
2171
2172    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2173        if (resumed) {
2174            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2175        } else {
2176            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2177        }
2178    }
2179
2180    boolean startHomeActivityLocked(int userId) {
2181        if (mHeadless) {
2182            // Added because none of the other calls to ensureBootCompleted seem to fire
2183            // when running headless.
2184            ensureBootCompleted();
2185            return false;
2186        }
2187
2188        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2189                && mTopAction == null) {
2190            // We are running in factory test mode, but unable to find
2191            // the factory test app, so just sit around displaying the
2192            // error message and don't try to start anything.
2193            return false;
2194        }
2195        Intent intent = new Intent(
2196            mTopAction,
2197            mTopData != null ? Uri.parse(mTopData) : null);
2198        intent.setComponent(mTopComponent);
2199        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2200            intent.addCategory(Intent.CATEGORY_HOME);
2201        }
2202        ActivityInfo aInfo =
2203            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2204        if (aInfo != null) {
2205            intent.setComponent(new ComponentName(
2206                    aInfo.applicationInfo.packageName, aInfo.name));
2207            // Don't do this if the home app is currently being
2208            // instrumented.
2209            aInfo = new ActivityInfo(aInfo);
2210            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2211            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2212                    aInfo.applicationInfo.uid);
2213            if (app == null || app.instrumentationClass == null) {
2214                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2215                mMainStack.startActivityLocked(null, intent, null, aInfo,
2216                        null, null, 0, 0, 0, 0, null, false, null);
2217            }
2218        }
2219
2220        return true;
2221    }
2222
2223    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2224        ActivityInfo ai = null;
2225        ComponentName comp = intent.getComponent();
2226        try {
2227            if (comp != null) {
2228                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2229            } else {
2230                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2231                        intent,
2232                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2233                            flags, userId);
2234
2235                if (info != null) {
2236                    ai = info.activityInfo;
2237                }
2238            }
2239        } catch (RemoteException e) {
2240            // ignore
2241        }
2242
2243        return ai;
2244    }
2245
2246    /**
2247     * Starts the "new version setup screen" if appropriate.
2248     */
2249    void startSetupActivityLocked() {
2250        // Only do this once per boot.
2251        if (mCheckedForSetup) {
2252            return;
2253        }
2254
2255        // We will show this screen if the current one is a different
2256        // version than the last one shown, and we are not running in
2257        // low-level factory test mode.
2258        final ContentResolver resolver = mContext.getContentResolver();
2259        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2260                Settings.Secure.getInt(resolver,
2261                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2262            mCheckedForSetup = true;
2263
2264            // See if we should be showing the platform update setup UI.
2265            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2266            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2267                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2268
2269            // We don't allow third party apps to replace this.
2270            ResolveInfo ri = null;
2271            for (int i=0; ris != null && i<ris.size(); i++) {
2272                if ((ris.get(i).activityInfo.applicationInfo.flags
2273                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2274                    ri = ris.get(i);
2275                    break;
2276                }
2277            }
2278
2279            if (ri != null) {
2280                String vers = ri.activityInfo.metaData != null
2281                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2282                        : null;
2283                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2284                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2285                            Intent.METADATA_SETUP_VERSION);
2286                }
2287                String lastVers = Settings.Secure.getString(
2288                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2289                if (vers != null && !vers.equals(lastVers)) {
2290                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2291                    intent.setComponent(new ComponentName(
2292                            ri.activityInfo.packageName, ri.activityInfo.name));
2293                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2294                            null, null, 0, 0, 0, 0, null, false, null);
2295                }
2296            }
2297        }
2298    }
2299
2300    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2301        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2302    }
2303
2304    void enforceNotIsolatedCaller(String caller) {
2305        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2306            throw new SecurityException("Isolated process not allowed to call " + caller);
2307        }
2308    }
2309
2310    public int getFrontActivityScreenCompatMode() {
2311        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2312        synchronized (this) {
2313            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2314        }
2315    }
2316
2317    public void setFrontActivityScreenCompatMode(int mode) {
2318        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2319                "setFrontActivityScreenCompatMode");
2320        synchronized (this) {
2321            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2322        }
2323    }
2324
2325    public int getPackageScreenCompatMode(String packageName) {
2326        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2327        synchronized (this) {
2328            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2329        }
2330    }
2331
2332    public void setPackageScreenCompatMode(String packageName, int mode) {
2333        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2334                "setPackageScreenCompatMode");
2335        synchronized (this) {
2336            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2337        }
2338    }
2339
2340    public boolean getPackageAskScreenCompat(String packageName) {
2341        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2342        synchronized (this) {
2343            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2344        }
2345    }
2346
2347    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2348        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2349                "setPackageAskScreenCompat");
2350        synchronized (this) {
2351            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2352        }
2353    }
2354
2355    void reportResumedActivityLocked(ActivityRecord r) {
2356        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2357        updateUsageStats(r, true);
2358    }
2359
2360    private void dispatchProcessesChanged() {
2361        int N;
2362        synchronized (this) {
2363            N = mPendingProcessChanges.size();
2364            if (mActiveProcessChanges.length < N) {
2365                mActiveProcessChanges = new ProcessChangeItem[N];
2366            }
2367            mPendingProcessChanges.toArray(mActiveProcessChanges);
2368            mAvailProcessChanges.addAll(mPendingProcessChanges);
2369            mPendingProcessChanges.clear();
2370            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2371        }
2372        int i = mProcessObservers.beginBroadcast();
2373        while (i > 0) {
2374            i--;
2375            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2376            if (observer != null) {
2377                try {
2378                    for (int j=0; j<N; j++) {
2379                        ProcessChangeItem item = mActiveProcessChanges[j];
2380                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2381                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2382                                    + item.pid + " uid=" + item.uid + ": "
2383                                    + item.foregroundActivities);
2384                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2385                                    item.foregroundActivities);
2386                        }
2387                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2388                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2389                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2390                            observer.onImportanceChanged(item.pid, item.uid,
2391                                    item.importance);
2392                        }
2393                    }
2394                } catch (RemoteException e) {
2395                }
2396            }
2397        }
2398        mProcessObservers.finishBroadcast();
2399    }
2400
2401    private void dispatchProcessDied(int pid, int uid) {
2402        int i = mProcessObservers.beginBroadcast();
2403        while (i > 0) {
2404            i--;
2405            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2406            if (observer != null) {
2407                try {
2408                    observer.onProcessDied(pid, uid);
2409                } catch (RemoteException e) {
2410                }
2411            }
2412        }
2413        mProcessObservers.finishBroadcast();
2414    }
2415
2416    final void doPendingActivityLaunchesLocked(boolean doResume) {
2417        final int N = mPendingActivityLaunches.size();
2418        if (N <= 0) {
2419            return;
2420        }
2421        for (int i=0; i<N; i++) {
2422            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2423            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2424                    pal.startFlags, doResume && i == (N-1), null);
2425        }
2426        mPendingActivityLaunches.clear();
2427    }
2428
2429    public final int startActivity(IApplicationThread caller,
2430            Intent intent, String resolvedType, IBinder resultTo,
2431            String resultWho, int requestCode, int startFlags,
2432            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2433        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2434                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2435    }
2436
2437    public final int startActivityAsUser(IApplicationThread caller,
2438            Intent intent, String resolvedType, IBinder resultTo,
2439            String resultWho, int requestCode, int startFlags,
2440            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2441        enforceNotIsolatedCaller("startActivity");
2442        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2443                false, true, "startActivity", null);
2444        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2445                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2446                null, null, options, userId);
2447    }
2448
2449    public final WaitResult startActivityAndWait(IApplicationThread caller,
2450            Intent intent, String resolvedType, IBinder resultTo,
2451            String resultWho, int requestCode, int startFlags, String profileFile,
2452            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2453        enforceNotIsolatedCaller("startActivityAndWait");
2454        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2455                false, true, "startActivityAndWait", null);
2456        WaitResult res = new WaitResult();
2457        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2458                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2459                res, null, options, UserHandle.getCallingUserId());
2460        return res;
2461    }
2462
2463    public final int startActivityWithConfig(IApplicationThread caller,
2464            Intent intent, String resolvedType, IBinder resultTo,
2465            String resultWho, int requestCode, int startFlags, Configuration config,
2466            Bundle options, int userId) {
2467        enforceNotIsolatedCaller("startActivityWithConfig");
2468        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2469                false, true, "startActivityWithConfig", null);
2470        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2471                resultTo, resultWho, requestCode, startFlags,
2472                null, null, null, config, options, userId);
2473        return ret;
2474    }
2475
2476    public int startActivityIntentSender(IApplicationThread caller,
2477            IntentSender intent, Intent fillInIntent, String resolvedType,
2478            IBinder resultTo, String resultWho, int requestCode,
2479            int flagsMask, int flagsValues, Bundle options) {
2480        enforceNotIsolatedCaller("startActivityIntentSender");
2481        // Refuse possible leaked file descriptors
2482        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2483            throw new IllegalArgumentException("File descriptors passed in Intent");
2484        }
2485
2486        IIntentSender sender = intent.getTarget();
2487        if (!(sender instanceof PendingIntentRecord)) {
2488            throw new IllegalArgumentException("Bad PendingIntent object");
2489        }
2490
2491        PendingIntentRecord pir = (PendingIntentRecord)sender;
2492
2493        synchronized (this) {
2494            // If this is coming from the currently resumed activity, it is
2495            // effectively saying that app switches are allowed at this point.
2496            if (mMainStack.mResumedActivity != null
2497                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2498                            Binder.getCallingUid()) {
2499                mAppSwitchesAllowedTime = 0;
2500            }
2501        }
2502        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2503                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2504        return ret;
2505    }
2506
2507    public boolean startNextMatchingActivity(IBinder callingActivity,
2508            Intent intent, Bundle options) {
2509        // Refuse possible leaked file descriptors
2510        if (intent != null && intent.hasFileDescriptors() == true) {
2511            throw new IllegalArgumentException("File descriptors passed in Intent");
2512        }
2513
2514        synchronized (this) {
2515            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2516            if (r == null) {
2517                ActivityOptions.abort(options);
2518                return false;
2519            }
2520            if (r.app == null || r.app.thread == null) {
2521                // The caller is not running...  d'oh!
2522                ActivityOptions.abort(options);
2523                return false;
2524            }
2525            intent = new Intent(intent);
2526            // The caller is not allowed to change the data.
2527            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2528            // And we are resetting to find the next component...
2529            intent.setComponent(null);
2530
2531            ActivityInfo aInfo = null;
2532            try {
2533                List<ResolveInfo> resolves =
2534                    AppGlobals.getPackageManager().queryIntentActivities(
2535                            intent, r.resolvedType,
2536                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2537                            UserHandle.getCallingUserId());
2538
2539                // Look for the original activity in the list...
2540                final int N = resolves != null ? resolves.size() : 0;
2541                for (int i=0; i<N; i++) {
2542                    ResolveInfo rInfo = resolves.get(i);
2543                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2544                            && rInfo.activityInfo.name.equals(r.info.name)) {
2545                        // We found the current one...  the next matching is
2546                        // after it.
2547                        i++;
2548                        if (i<N) {
2549                            aInfo = resolves.get(i).activityInfo;
2550                        }
2551                        break;
2552                    }
2553                }
2554            } catch (RemoteException e) {
2555            }
2556
2557            if (aInfo == null) {
2558                // Nobody who is next!
2559                ActivityOptions.abort(options);
2560                return false;
2561            }
2562
2563            intent.setComponent(new ComponentName(
2564                    aInfo.applicationInfo.packageName, aInfo.name));
2565            intent.setFlags(intent.getFlags()&~(
2566                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2567                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2568                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2569                    Intent.FLAG_ACTIVITY_NEW_TASK));
2570
2571            // Okay now we need to start the new activity, replacing the
2572            // currently running activity.  This is a little tricky because
2573            // we want to start the new one as if the current one is finished,
2574            // but not finish the current one first so that there is no flicker.
2575            // And thus...
2576            final boolean wasFinishing = r.finishing;
2577            r.finishing = true;
2578
2579            // Propagate reply information over to the new activity.
2580            final ActivityRecord resultTo = r.resultTo;
2581            final String resultWho = r.resultWho;
2582            final int requestCode = r.requestCode;
2583            r.resultTo = null;
2584            if (resultTo != null) {
2585                resultTo.removeResultsLocked(r, resultWho, requestCode);
2586            }
2587
2588            final long origId = Binder.clearCallingIdentity();
2589            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2590                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2591                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2592                    options, false, null);
2593            Binder.restoreCallingIdentity(origId);
2594
2595            r.finishing = wasFinishing;
2596            if (res != ActivityManager.START_SUCCESS) {
2597                return false;
2598            }
2599            return true;
2600        }
2601    }
2602
2603    final int startActivityInPackage(int uid,
2604            Intent intent, String resolvedType, IBinder resultTo,
2605            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2606
2607        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2608                false, true, "startActivityInPackage", null);
2609
2610        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2611                resultTo, resultWho, requestCode, startFlags,
2612                null, null, null, null, options, userId);
2613        return ret;
2614    }
2615
2616    public final int startActivities(IApplicationThread caller,
2617            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2618        enforceNotIsolatedCaller("startActivities");
2619        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2620                options, UserHandle.getCallingUserId());
2621        return ret;
2622    }
2623
2624    final int startActivitiesInPackage(int uid,
2625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2626            Bundle options, int userId) {
2627
2628        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2629                false, true, "startActivityInPackage", null);
2630        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2631                options, userId);
2632        return ret;
2633    }
2634
2635    final void addRecentTaskLocked(TaskRecord task) {
2636        int N = mRecentTasks.size();
2637        // Quick case: check if the top-most recent task is the same.
2638        if (N > 0 && mRecentTasks.get(0) == task) {
2639            return;
2640        }
2641        // Remove any existing entries that are the same kind of task.
2642        for (int i=0; i<N; i++) {
2643            TaskRecord tr = mRecentTasks.get(i);
2644            if (task.userId == tr.userId
2645                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2646                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2647                mRecentTasks.remove(i);
2648                i--;
2649                N--;
2650                if (task.intent == null) {
2651                    // If the new recent task we are adding is not fully
2652                    // specified, then replace it with the existing recent task.
2653                    task = tr;
2654                }
2655            }
2656        }
2657        if (N >= MAX_RECENT_TASKS) {
2658            mRecentTasks.remove(N-1);
2659        }
2660        mRecentTasks.add(0, task);
2661    }
2662
2663    public void setRequestedOrientation(IBinder token,
2664            int requestedOrientation) {
2665        synchronized (this) {
2666            ActivityRecord r = mMainStack.isInStackLocked(token);
2667            if (r == null) {
2668                return;
2669            }
2670            final long origId = Binder.clearCallingIdentity();
2671            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2672            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2673                    mConfiguration,
2674                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2675            if (config != null) {
2676                r.frozenBeforeDestroy = true;
2677                if (!updateConfigurationLocked(config, r, false, false)) {
2678                    mMainStack.resumeTopActivityLocked(null);
2679                }
2680            }
2681            Binder.restoreCallingIdentity(origId);
2682        }
2683    }
2684
2685    public int getRequestedOrientation(IBinder token) {
2686        synchronized (this) {
2687            ActivityRecord r = mMainStack.isInStackLocked(token);
2688            if (r == null) {
2689                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2690            }
2691            return mWindowManager.getAppOrientation(r.appToken);
2692        }
2693    }
2694
2695    /**
2696     * This is the internal entry point for handling Activity.finish().
2697     *
2698     * @param token The Binder token referencing the Activity we want to finish.
2699     * @param resultCode Result code, if any, from this Activity.
2700     * @param resultData Result data (Intent), if any, from this Activity.
2701     *
2702     * @return Returns true if the activity successfully finished, or false if it is still running.
2703     */
2704    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2705        // Refuse possible leaked file descriptors
2706        if (resultData != null && resultData.hasFileDescriptors() == true) {
2707            throw new IllegalArgumentException("File descriptors passed in Intent");
2708        }
2709
2710        synchronized(this) {
2711            if (mController != null) {
2712                // Find the first activity that is not finishing.
2713                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2714                if (next != null) {
2715                    // ask watcher if this is allowed
2716                    boolean resumeOK = true;
2717                    try {
2718                        resumeOK = mController.activityResuming(next.packageName);
2719                    } catch (RemoteException e) {
2720                        mController = null;
2721                    }
2722
2723                    if (!resumeOK) {
2724                        return false;
2725                    }
2726                }
2727            }
2728            final long origId = Binder.clearCallingIdentity();
2729            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2730                    resultData, "app-request", true);
2731            Binder.restoreCallingIdentity(origId);
2732            return res;
2733        }
2734    }
2735
2736    public final void finishHeavyWeightApp() {
2737        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2738                != PackageManager.PERMISSION_GRANTED) {
2739            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2740                    + Binder.getCallingPid()
2741                    + ", uid=" + Binder.getCallingUid()
2742                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2743            Slog.w(TAG, msg);
2744            throw new SecurityException(msg);
2745        }
2746
2747        synchronized(this) {
2748            if (mHeavyWeightProcess == null) {
2749                return;
2750            }
2751
2752            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2753                    mHeavyWeightProcess.activities);
2754            for (int i=0; i<activities.size(); i++) {
2755                ActivityRecord r = activities.get(i);
2756                if (!r.finishing) {
2757                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2758                    if (index >= 0) {
2759                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2760                                null, "finish-heavy", true);
2761                    }
2762                }
2763            }
2764
2765            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2766                    mHeavyWeightProcess.userId, 0));
2767            mHeavyWeightProcess = null;
2768        }
2769    }
2770
2771    public void crashApplication(int uid, int initialPid, String packageName,
2772            String message) {
2773        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2774                != PackageManager.PERMISSION_GRANTED) {
2775            String msg = "Permission Denial: crashApplication() from pid="
2776                    + Binder.getCallingPid()
2777                    + ", uid=" + Binder.getCallingUid()
2778                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2779            Slog.w(TAG, msg);
2780            throw new SecurityException(msg);
2781        }
2782
2783        synchronized(this) {
2784            ProcessRecord proc = null;
2785
2786            // Figure out which process to kill.  We don't trust that initialPid
2787            // still has any relation to current pids, so must scan through the
2788            // list.
2789            synchronized (mPidsSelfLocked) {
2790                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2791                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2792                    if (p.uid != uid) {
2793                        continue;
2794                    }
2795                    if (p.pid == initialPid) {
2796                        proc = p;
2797                        break;
2798                    }
2799                    for (String str : p.pkgList) {
2800                        if (str.equals(packageName)) {
2801                            proc = p;
2802                        }
2803                    }
2804                }
2805            }
2806
2807            if (proc == null) {
2808                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2809                        + " initialPid=" + initialPid
2810                        + " packageName=" + packageName);
2811                return;
2812            }
2813
2814            if (proc.thread != null) {
2815                if (proc.pid == Process.myPid()) {
2816                    Log.w(TAG, "crashApplication: trying to crash self!");
2817                    return;
2818                }
2819                long ident = Binder.clearCallingIdentity();
2820                try {
2821                    proc.thread.scheduleCrash(message);
2822                } catch (RemoteException e) {
2823                }
2824                Binder.restoreCallingIdentity(ident);
2825            }
2826        }
2827    }
2828
2829    public final void finishSubActivity(IBinder token, String resultWho,
2830            int requestCode) {
2831        synchronized(this) {
2832            final long origId = Binder.clearCallingIdentity();
2833            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2834            Binder.restoreCallingIdentity(origId);
2835        }
2836    }
2837
2838    public boolean finishActivityAffinity(IBinder token) {
2839        synchronized(this) {
2840            final long origId = Binder.clearCallingIdentity();
2841            boolean res = mMainStack.finishActivityAffinityLocked(token);
2842            Binder.restoreCallingIdentity(origId);
2843            return res;
2844        }
2845    }
2846
2847    public boolean willActivityBeVisible(IBinder token) {
2848        synchronized(this) {
2849            int i;
2850            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2851                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2852                if (r.appToken == token) {
2853                    return true;
2854                }
2855                if (r.fullscreen && !r.finishing) {
2856                    return false;
2857                }
2858            }
2859            return true;
2860        }
2861    }
2862
2863    public void overridePendingTransition(IBinder token, String packageName,
2864            int enterAnim, int exitAnim) {
2865        synchronized(this) {
2866            ActivityRecord self = mMainStack.isInStackLocked(token);
2867            if (self == null) {
2868                return;
2869            }
2870
2871            final long origId = Binder.clearCallingIdentity();
2872
2873            if (self.state == ActivityState.RESUMED
2874                    || self.state == ActivityState.PAUSING) {
2875                mWindowManager.overridePendingAppTransition(packageName,
2876                        enterAnim, exitAnim, null);
2877            }
2878
2879            Binder.restoreCallingIdentity(origId);
2880        }
2881    }
2882
2883    /**
2884     * Main function for removing an existing process from the activity manager
2885     * as a result of that process going away.  Clears out all connections
2886     * to the process.
2887     */
2888    private final void handleAppDiedLocked(ProcessRecord app,
2889            boolean restarting, boolean allowRestart) {
2890        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2891        if (!restarting) {
2892            mLruProcesses.remove(app);
2893        }
2894
2895        if (mProfileProc == app) {
2896            clearProfilerLocked();
2897        }
2898
2899        // Just in case...
2900        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2901            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2902            mMainStack.mPausingActivity = null;
2903        }
2904        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2905            mMainStack.mLastPausedActivity = null;
2906        }
2907
2908        // Remove this application's activities from active lists.
2909        mMainStack.removeHistoryRecordsForAppLocked(app);
2910
2911        boolean atTop = true;
2912        boolean hasVisibleActivities = false;
2913
2914        // Clean out the history list.
2915        int i = mMainStack.mHistory.size();
2916        if (localLOGV) Slog.v(
2917            TAG, "Removing app " + app + " from history with " + i + " entries");
2918        while (i > 0) {
2919            i--;
2920            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2921            if (localLOGV) Slog.v(
2922                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2923            if (r.app == app) {
2924                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2925                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2926                        RuntimeException here = new RuntimeException("here");
2927                        here.fillInStackTrace();
2928                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2929                                + ": haveState=" + r.haveState
2930                                + " stateNotNeeded=" + r.stateNotNeeded
2931                                + " finishing=" + r.finishing
2932                                + " state=" + r.state, here);
2933                    }
2934                    if (!r.finishing) {
2935                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2936                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2937                                System.identityHashCode(r),
2938                                r.task.taskId, r.shortComponentName,
2939                                "proc died without state saved");
2940                    }
2941                    mMainStack.removeActivityFromHistoryLocked(r);
2942
2943                } else {
2944                    // We have the current state for this activity, so
2945                    // it can be restarted later when needed.
2946                    if (localLOGV) Slog.v(
2947                        TAG, "Keeping entry, setting app to null");
2948                    if (r.visible) {
2949                        hasVisibleActivities = true;
2950                    }
2951                    r.app = null;
2952                    r.nowVisible = false;
2953                    if (!r.haveState) {
2954                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2955                                "App died, clearing saved state of " + r);
2956                        r.icicle = null;
2957                    }
2958                }
2959
2960                r.stack.cleanUpActivityLocked(r, true, true);
2961            }
2962            atTop = false;
2963        }
2964
2965        app.activities.clear();
2966
2967        if (app.instrumentationClass != null) {
2968            Slog.w(TAG, "Crash of app " + app.processName
2969                  + " running instrumentation " + app.instrumentationClass);
2970            Bundle info = new Bundle();
2971            info.putString("shortMsg", "Process crashed.");
2972            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2973        }
2974
2975        if (!restarting) {
2976            if (!mMainStack.resumeTopActivityLocked(null)) {
2977                // If there was nothing to resume, and we are not already
2978                // restarting this process, but there is a visible activity that
2979                // is hosted by the process...  then make sure all visible
2980                // activities are running, taking care of restarting this
2981                // process.
2982                if (hasVisibleActivities) {
2983                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2984                }
2985            }
2986        }
2987    }
2988
2989    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2990        IBinder threadBinder = thread.asBinder();
2991        // Find the application record.
2992        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2993            ProcessRecord rec = mLruProcesses.get(i);
2994            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2995                return i;
2996            }
2997        }
2998        return -1;
2999    }
3000
3001    final ProcessRecord getRecordForAppLocked(
3002            IApplicationThread thread) {
3003        if (thread == null) {
3004            return null;
3005        }
3006
3007        int appIndex = getLRURecordIndexForAppLocked(thread);
3008        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3009    }
3010
3011    final void appDiedLocked(ProcessRecord app, int pid,
3012            IApplicationThread thread) {
3013
3014        mProcDeaths[0]++;
3015
3016        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3017        synchronized (stats) {
3018            stats.noteProcessDiedLocked(app.info.uid, pid);
3019        }
3020
3021        // Clean up already done if the process has been re-started.
3022        if (app.pid == pid && app.thread != null &&
3023                app.thread.asBinder() == thread.asBinder()) {
3024            if (!app.killedBackground) {
3025                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3026                        + ") has died.");
3027            }
3028            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3029            if (localLOGV) Slog.v(
3030                TAG, "Dying app: " + app + ", pid: " + pid
3031                + ", thread: " + thread.asBinder());
3032            boolean doLowMem = app.instrumentationClass == null;
3033            handleAppDiedLocked(app, false, true);
3034
3035            if (doLowMem) {
3036                // If there are no longer any background processes running,
3037                // and the app that died was not running instrumentation,
3038                // then tell everyone we are now low on memory.
3039                boolean haveBg = false;
3040                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3041                    ProcessRecord rec = mLruProcesses.get(i);
3042                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3043                        haveBg = true;
3044                        break;
3045                    }
3046                }
3047
3048                if (!haveBg) {
3049                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3050                    long now = SystemClock.uptimeMillis();
3051                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3052                        ProcessRecord rec = mLruProcesses.get(i);
3053                        if (rec != app && rec.thread != null &&
3054                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3055                            // The low memory report is overriding any current
3056                            // state for a GC request.  Make sure to do
3057                            // heavy/important/visible/foreground processes first.
3058                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3059                                rec.lastRequestedGc = 0;
3060                            } else {
3061                                rec.lastRequestedGc = rec.lastLowMemory;
3062                            }
3063                            rec.reportLowMemory = true;
3064                            rec.lastLowMemory = now;
3065                            mProcessesToGc.remove(rec);
3066                            addProcessToGcListLocked(rec);
3067                        }
3068                    }
3069                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3070                    scheduleAppGcsLocked();
3071                }
3072            }
3073        } else if (app.pid != pid) {
3074            // A new process has already been started.
3075            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3076                    + ") has died and restarted (pid " + app.pid + ").");
3077            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3078        } else if (DEBUG_PROCESSES) {
3079            Slog.d(TAG, "Received spurious death notification for thread "
3080                    + thread.asBinder());
3081        }
3082    }
3083
3084    /**
3085     * If a stack trace dump file is configured, dump process stack traces.
3086     * @param clearTraces causes the dump file to be erased prior to the new
3087     *    traces being written, if true; when false, the new traces will be
3088     *    appended to any existing file content.
3089     * @param firstPids of dalvik VM processes to dump stack traces for first
3090     * @param lastPids of dalvik VM processes to dump stack traces for last
3091     * @param nativeProcs optional list of native process names to dump stack crawls
3092     * @return file containing stack traces, or null if no dump file is configured
3093     */
3094    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3095            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3096        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3097        if (tracesPath == null || tracesPath.length() == 0) {
3098            return null;
3099        }
3100
3101        File tracesFile = new File(tracesPath);
3102        try {
3103            File tracesDir = tracesFile.getParentFile();
3104            if (!tracesDir.exists()) {
3105                tracesFile.mkdirs();
3106                if (!SELinux.restorecon(tracesDir)) {
3107                    return null;
3108                }
3109            }
3110            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3111
3112            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3113            tracesFile.createNewFile();
3114            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3115        } catch (IOException e) {
3116            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3117            return null;
3118        }
3119
3120        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3121        return tracesFile;
3122    }
3123
3124    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3125            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3126        // Use a FileObserver to detect when traces finish writing.
3127        // The order of traces is considered important to maintain for legibility.
3128        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3129            public synchronized void onEvent(int event, String path) { notify(); }
3130        };
3131
3132        try {
3133            observer.startWatching();
3134
3135            // First collect all of the stacks of the most important pids.
3136            if (firstPids != null) {
3137                try {
3138                    int num = firstPids.size();
3139                    for (int i = 0; i < num; i++) {
3140                        synchronized (observer) {
3141                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3142                            observer.wait(200);  // Wait for write-close, give up after 200msec
3143                        }
3144                    }
3145                } catch (InterruptedException e) {
3146                    Log.wtf(TAG, e);
3147                }
3148            }
3149
3150            // Next measure CPU usage.
3151            if (processStats != null) {
3152                processStats.init();
3153                System.gc();
3154                processStats.update();
3155                try {
3156                    synchronized (processStats) {
3157                        processStats.wait(500); // measure over 1/2 second.
3158                    }
3159                } catch (InterruptedException e) {
3160                }
3161                processStats.update();
3162
3163                // We'll take the stack crawls of just the top apps using CPU.
3164                final int N = processStats.countWorkingStats();
3165                int numProcs = 0;
3166                for (int i=0; i<N && numProcs<5; i++) {
3167                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3168                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3169                        numProcs++;
3170                        try {
3171                            synchronized (observer) {
3172                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3173                                observer.wait(200);  // Wait for write-close, give up after 200msec
3174                            }
3175                        } catch (InterruptedException e) {
3176                            Log.wtf(TAG, e);
3177                        }
3178
3179                    }
3180                }
3181            }
3182
3183        } finally {
3184            observer.stopWatching();
3185        }
3186
3187        if (nativeProcs != null) {
3188            int[] pids = Process.getPidsForCommands(nativeProcs);
3189            if (pids != null) {
3190                for (int pid : pids) {
3191                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3192                }
3193            }
3194        }
3195    }
3196
3197    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3198        if (true || IS_USER_BUILD) {
3199            return;
3200        }
3201        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3202        if (tracesPath == null || tracesPath.length() == 0) {
3203            return;
3204        }
3205
3206        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3207        StrictMode.allowThreadDiskWrites();
3208        try {
3209            final File tracesFile = new File(tracesPath);
3210            final File tracesDir = tracesFile.getParentFile();
3211            final File tracesTmp = new File(tracesDir, "__tmp__");
3212            try {
3213                if (!tracesDir.exists()) {
3214                    tracesFile.mkdirs();
3215                    if (!SELinux.restorecon(tracesDir.getPath())) {
3216                        return;
3217                    }
3218                }
3219                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3220
3221                if (tracesFile.exists()) {
3222                    tracesTmp.delete();
3223                    tracesFile.renameTo(tracesTmp);
3224                }
3225                StringBuilder sb = new StringBuilder();
3226                Time tobj = new Time();
3227                tobj.set(System.currentTimeMillis());
3228                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3229                sb.append(": ");
3230                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3231                sb.append(" since ");
3232                sb.append(msg);
3233                FileOutputStream fos = new FileOutputStream(tracesFile);
3234                fos.write(sb.toString().getBytes());
3235                if (app == null) {
3236                    fos.write("\n*** No application process!".getBytes());
3237                }
3238                fos.close();
3239                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3240            } catch (IOException e) {
3241                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3242                return;
3243            }
3244
3245            if (app != null) {
3246                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3247                firstPids.add(app.pid);
3248                dumpStackTraces(tracesPath, firstPids, null, null, null);
3249            }
3250
3251            File lastTracesFile = null;
3252            File curTracesFile = null;
3253            for (int i=9; i>=0; i--) {
3254                String name = String.format("slow%02d.txt", i);
3255                curTracesFile = new File(tracesDir, name);
3256                if (curTracesFile.exists()) {
3257                    if (lastTracesFile != null) {
3258                        curTracesFile.renameTo(lastTracesFile);
3259                    } else {
3260                        curTracesFile.delete();
3261                    }
3262                }
3263                lastTracesFile = curTracesFile;
3264            }
3265            tracesFile.renameTo(curTracesFile);
3266            if (tracesTmp.exists()) {
3267                tracesTmp.renameTo(tracesFile);
3268            }
3269        } finally {
3270            StrictMode.setThreadPolicy(oldPolicy);
3271        }
3272    }
3273
3274    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3275            ActivityRecord parent, final String annotation) {
3276        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3277        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3278
3279        if (mController != null) {
3280            try {
3281                // 0 == continue, -1 = kill process immediately
3282                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3283                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3284            } catch (RemoteException e) {
3285                mController = null;
3286            }
3287        }
3288
3289        long anrTime = SystemClock.uptimeMillis();
3290        if (MONITOR_CPU_USAGE) {
3291            updateCpuStatsNow();
3292        }
3293
3294        synchronized (this) {
3295            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3296            if (mShuttingDown) {
3297                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3298                return;
3299            } else if (app.notResponding) {
3300                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3301                return;
3302            } else if (app.crashing) {
3303                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3304                return;
3305            }
3306
3307            // In case we come through here for the same app before completing
3308            // this one, mark as anring now so we will bail out.
3309            app.notResponding = true;
3310
3311            // Log the ANR to the event log.
3312            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3313                    annotation);
3314
3315            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3316            firstPids.add(app.pid);
3317
3318            int parentPid = app.pid;
3319            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3320            if (parentPid != app.pid) firstPids.add(parentPid);
3321
3322            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3323
3324            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3325                ProcessRecord r = mLruProcesses.get(i);
3326                if (r != null && r.thread != null) {
3327                    int pid = r.pid;
3328                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3329                        if (r.persistent) {
3330                            firstPids.add(pid);
3331                        } else {
3332                            lastPids.put(pid, Boolean.TRUE);
3333                        }
3334                    }
3335                }
3336            }
3337        }
3338
3339        // Log the ANR to the main log.
3340        StringBuilder info = new StringBuilder();
3341        info.setLength(0);
3342        info.append("ANR in ").append(app.processName);
3343        if (activity != null && activity.shortComponentName != null) {
3344            info.append(" (").append(activity.shortComponentName).append(")");
3345        }
3346        info.append("\n");
3347        if (annotation != null) {
3348            info.append("Reason: ").append(annotation).append("\n");
3349        }
3350        if (parent != null && parent != activity) {
3351            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3352        }
3353
3354        final ProcessStats processStats = new ProcessStats(true);
3355
3356        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3357
3358        String cpuInfo = null;
3359        if (MONITOR_CPU_USAGE) {
3360            updateCpuStatsNow();
3361            synchronized (mProcessStatsThread) {
3362                cpuInfo = mProcessStats.printCurrentState(anrTime);
3363            }
3364            info.append(processStats.printCurrentLoad());
3365            info.append(cpuInfo);
3366        }
3367
3368        info.append(processStats.printCurrentState(anrTime));
3369
3370        Slog.e(TAG, info.toString());
3371        if (tracesFile == null) {
3372            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3373            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3374        }
3375
3376        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3377                cpuInfo, tracesFile, null);
3378
3379        if (mController != null) {
3380            try {
3381                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3382                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3383                if (res != 0) {
3384                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3385                    return;
3386                }
3387            } catch (RemoteException e) {
3388                mController = null;
3389            }
3390        }
3391
3392        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3393        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3394                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3395
3396        synchronized (this) {
3397            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3398                Slog.w(TAG, "Killing " + app + ": background ANR");
3399                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3400                        app.processName, app.setAdj, "background ANR");
3401                Process.killProcessQuiet(app.pid);
3402                return;
3403            }
3404
3405            // Set the app's notResponding state, and look up the errorReportReceiver
3406            makeAppNotRespondingLocked(app,
3407                    activity != null ? activity.shortComponentName : null,
3408                    annotation != null ? "ANR " + annotation : "ANR",
3409                    info.toString());
3410
3411            // Bring up the infamous App Not Responding dialog
3412            Message msg = Message.obtain();
3413            HashMap map = new HashMap();
3414            msg.what = SHOW_NOT_RESPONDING_MSG;
3415            msg.obj = map;
3416            map.put("app", app);
3417            if (activity != null) {
3418                map.put("activity", activity);
3419            }
3420
3421            mHandler.sendMessage(msg);
3422        }
3423    }
3424
3425    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3426        if (!mLaunchWarningShown) {
3427            mLaunchWarningShown = true;
3428            mHandler.post(new Runnable() {
3429                @Override
3430                public void run() {
3431                    synchronized (ActivityManagerService.this) {
3432                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3433                        d.show();
3434                        mHandler.postDelayed(new Runnable() {
3435                            @Override
3436                            public void run() {
3437                                synchronized (ActivityManagerService.this) {
3438                                    d.dismiss();
3439                                    mLaunchWarningShown = false;
3440                                }
3441                            }
3442                        }, 4000);
3443                    }
3444                }
3445            });
3446        }
3447    }
3448
3449    public boolean clearApplicationUserData(final String packageName,
3450            final IPackageDataObserver observer, int userId) {
3451        enforceNotIsolatedCaller("clearApplicationUserData");
3452        int uid = Binder.getCallingUid();
3453        int pid = Binder.getCallingPid();
3454        userId = handleIncomingUserLocked(pid, uid,
3455                userId, false, true, "clearApplicationUserData", null);
3456        long callingId = Binder.clearCallingIdentity();
3457        try {
3458            IPackageManager pm = AppGlobals.getPackageManager();
3459            int pkgUid = -1;
3460            synchronized(this) {
3461                try {
3462                    pkgUid = pm.getPackageUid(packageName, userId);
3463                } catch (RemoteException e) {
3464                }
3465                if (pkgUid == -1) {
3466                    Slog.w(TAG, "Invalid packageName:" + packageName);
3467                    return false;
3468                }
3469                if (uid == pkgUid || checkComponentPermission(
3470                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3471                        pid, uid, -1, true)
3472                        == PackageManager.PERMISSION_GRANTED) {
3473                    forceStopPackageLocked(packageName, pkgUid);
3474                } else {
3475                    throw new SecurityException(pid+" does not have permission:"+
3476                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3477                                    "for process:"+packageName);
3478                }
3479            }
3480
3481            try {
3482                //clear application user data
3483                pm.clearApplicationUserData(packageName, observer, userId);
3484                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3485                        Uri.fromParts("package", packageName, null));
3486                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3487                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3488                        null, null, 0, null, null, null, false, false, userId);
3489            } catch (RemoteException e) {
3490            }
3491        } finally {
3492            Binder.restoreCallingIdentity(callingId);
3493        }
3494        return true;
3495    }
3496
3497    public void killBackgroundProcesses(final String packageName, int userId) {
3498        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3499                != PackageManager.PERMISSION_GRANTED &&
3500                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3501                        != PackageManager.PERMISSION_GRANTED) {
3502            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3503                    + Binder.getCallingPid()
3504                    + ", uid=" + Binder.getCallingUid()
3505                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3506            Slog.w(TAG, msg);
3507            throw new SecurityException(msg);
3508        }
3509
3510        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3511                userId, true, true, "killBackgroundProcesses", null);
3512        long callingId = Binder.clearCallingIdentity();
3513        try {
3514            IPackageManager pm = AppGlobals.getPackageManager();
3515            synchronized(this) {
3516                int appId = -1;
3517                try {
3518                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3519                } catch (RemoteException e) {
3520                }
3521                if (appId == -1) {
3522                    Slog.w(TAG, "Invalid packageName: " + packageName);
3523                    return;
3524                }
3525                killPackageProcessesLocked(packageName, appId, userId,
3526                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3527            }
3528        } finally {
3529            Binder.restoreCallingIdentity(callingId);
3530        }
3531    }
3532
3533    public void killAllBackgroundProcesses() {
3534        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3535                != PackageManager.PERMISSION_GRANTED) {
3536            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3537                    + Binder.getCallingPid()
3538                    + ", uid=" + Binder.getCallingUid()
3539                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3540            Slog.w(TAG, msg);
3541            throw new SecurityException(msg);
3542        }
3543
3544        long callingId = Binder.clearCallingIdentity();
3545        try {
3546            synchronized(this) {
3547                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3548                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3549                    final int NA = apps.size();
3550                    for (int ia=0; ia<NA; ia++) {
3551                        ProcessRecord app = apps.valueAt(ia);
3552                        if (app.persistent) {
3553                            // we don't kill persistent processes
3554                            continue;
3555                        }
3556                        if (app.removed) {
3557                            procs.add(app);
3558                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3559                            app.removed = true;
3560                            procs.add(app);
3561                        }
3562                    }
3563                }
3564
3565                int N = procs.size();
3566                for (int i=0; i<N; i++) {
3567                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3568                }
3569            }
3570        } finally {
3571            Binder.restoreCallingIdentity(callingId);
3572        }
3573    }
3574
3575    public void forceStopPackage(final String packageName, int userId) {
3576        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3577                != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: forceStopPackage() from pid="
3579                    + Binder.getCallingPid()
3580                    + ", uid=" + Binder.getCallingUid()
3581                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3582            Slog.w(TAG, msg);
3583            throw new SecurityException(msg);
3584        }
3585        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3586                userId, true, true, "forceStopPackage", null);
3587        long callingId = Binder.clearCallingIdentity();
3588        try {
3589            IPackageManager pm = AppGlobals.getPackageManager();
3590            synchronized(this) {
3591                int[] users = userId == UserHandle.USER_ALL
3592                        ? getUsersLocked() : new int[] { userId };
3593                for (int user : users) {
3594                    int pkgUid = -1;
3595                    try {
3596                        pkgUid = pm.getPackageUid(packageName, user);
3597                    } catch (RemoteException e) {
3598                    }
3599                    if (pkgUid == -1) {
3600                        Slog.w(TAG, "Invalid packageName: " + packageName);
3601                        continue;
3602                    }
3603                    try {
3604                        pm.setPackageStoppedState(packageName, true, user);
3605                    } catch (RemoteException e) {
3606                    } catch (IllegalArgumentException e) {
3607                        Slog.w(TAG, "Failed trying to unstop package "
3608                                + packageName + ": " + e);
3609                    }
3610                    if (isUserRunningLocked(user)) {
3611                        forceStopPackageLocked(packageName, pkgUid);
3612                    }
3613                }
3614            }
3615        } finally {
3616            Binder.restoreCallingIdentity(callingId);
3617        }
3618    }
3619
3620    /*
3621     * The pkg name and app id have to be specified.
3622     */
3623    public void killApplicationWithAppId(String pkg, int appid) {
3624        if (pkg == null) {
3625            return;
3626        }
3627        // Make sure the uid is valid.
3628        if (appid < 0) {
3629            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3630            return;
3631        }
3632        int callerUid = Binder.getCallingUid();
3633        // Only the system server can kill an application
3634        if (callerUid == Process.SYSTEM_UID) {
3635            // Post an aysnc message to kill the application
3636            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3637            msg.arg1 = appid;
3638            msg.arg2 = 0;
3639            msg.obj = pkg;
3640            mHandler.sendMessage(msg);
3641        } else {
3642            throw new SecurityException(callerUid + " cannot kill pkg: " +
3643                    pkg);
3644        }
3645    }
3646
3647    public void closeSystemDialogs(String reason) {
3648        enforceNotIsolatedCaller("closeSystemDialogs");
3649
3650        final int pid = Binder.getCallingPid();
3651        final int uid = Binder.getCallingUid();
3652        final long origId = Binder.clearCallingIdentity();
3653        try {
3654            synchronized (this) {
3655                // Only allow this from foreground processes, so that background
3656                // applications can't abuse it to prevent system UI from being shown.
3657                if (uid >= Process.FIRST_APPLICATION_UID) {
3658                    ProcessRecord proc;
3659                    synchronized (mPidsSelfLocked) {
3660                        proc = mPidsSelfLocked.get(pid);
3661                    }
3662                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3663                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3664                                + " from background process " + proc);
3665                        return;
3666                    }
3667                }
3668                closeSystemDialogsLocked(reason);
3669            }
3670        } finally {
3671            Binder.restoreCallingIdentity(origId);
3672        }
3673    }
3674
3675    void closeSystemDialogsLocked(String reason) {
3676        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3677        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3678        if (reason != null) {
3679            intent.putExtra("reason", reason);
3680        }
3681        mWindowManager.closeSystemDialogs(reason);
3682
3683        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3684            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3685            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3686                r.stack.finishActivityLocked(r, i,
3687                        Activity.RESULT_CANCELED, null, "close-sys", true);
3688            }
3689        }
3690
3691        broadcastIntentLocked(null, null, intent, null,
3692                null, 0, null, null, null, false, false, -1,
3693                Process.SYSTEM_UID, UserHandle.USER_ALL);
3694    }
3695
3696    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3697            throws RemoteException {
3698        enforceNotIsolatedCaller("getProcessMemoryInfo");
3699        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3700        for (int i=pids.length-1; i>=0; i--) {
3701            infos[i] = new Debug.MemoryInfo();
3702            Debug.getMemoryInfo(pids[i], infos[i]);
3703        }
3704        return infos;
3705    }
3706
3707    public long[] getProcessPss(int[] pids) throws RemoteException {
3708        enforceNotIsolatedCaller("getProcessPss");
3709        long[] pss = new long[pids.length];
3710        for (int i=pids.length-1; i>=0; i--) {
3711            pss[i] = Debug.getPss(pids[i]);
3712        }
3713        return pss;
3714    }
3715
3716    public void killApplicationProcess(String processName, int uid) {
3717        if (processName == null) {
3718            return;
3719        }
3720
3721        int callerUid = Binder.getCallingUid();
3722        // Only the system server can kill an application
3723        if (callerUid == Process.SYSTEM_UID) {
3724            synchronized (this) {
3725                ProcessRecord app = getProcessRecordLocked(processName, uid);
3726                if (app != null && app.thread != null) {
3727                    try {
3728                        app.thread.scheduleSuicide();
3729                    } catch (RemoteException e) {
3730                        // If the other end already died, then our work here is done.
3731                    }
3732                } else {
3733                    Slog.w(TAG, "Process/uid not found attempting kill of "
3734                            + processName + " / " + uid);
3735                }
3736            }
3737        } else {
3738            throw new SecurityException(callerUid + " cannot kill app process: " +
3739                    processName);
3740        }
3741    }
3742
3743    private void forceStopPackageLocked(final String packageName, int uid) {
3744        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3745                false, true, false, UserHandle.getUserId(uid));
3746        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3747                Uri.fromParts("package", packageName, null));
3748        if (!mProcessesReady) {
3749            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3750        }
3751        intent.putExtra(Intent.EXTRA_UID, uid);
3752        broadcastIntentLocked(null, null, intent,
3753                null, null, 0, null, null, null,
3754                false, false,
3755                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3756    }
3757
3758    private void forceStopUserLocked(int userId) {
3759        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3760        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3761        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3762        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3763        broadcastIntentLocked(null, null, intent,
3764                null, null, 0, null, null, null,
3765                false, false,
3766                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3767    }
3768
3769    private final boolean killPackageProcessesLocked(String packageName, int appId,
3770            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3771            boolean doit, boolean evenPersistent, String reason) {
3772        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3773
3774        // Remove all processes this package may have touched: all with the
3775        // same UID (except for the system or root user), and all whose name
3776        // matches the package name.
3777        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3778        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3779            final int NA = apps.size();
3780            for (int ia=0; ia<NA; ia++) {
3781                ProcessRecord app = apps.valueAt(ia);
3782                if (app.persistent && !evenPersistent) {
3783                    // we don't kill persistent processes
3784                    continue;
3785                }
3786                if (app.removed) {
3787                    if (doit) {
3788                        procs.add(app);
3789                    }
3790                    continue;
3791                }
3792
3793                // Skip process if it doesn't meet our oom adj requirement.
3794                if (app.setAdj < minOomAdj) {
3795                    continue;
3796                }
3797
3798                // If no package is specified, we call all processes under the
3799                // give user id.
3800                if (packageName == null) {
3801                    if (app.userId != userId) {
3802                        continue;
3803                    }
3804                // Package has been specified, we want to hit all processes
3805                // that match it.  We need to qualify this by the processes
3806                // that are running under the specified app and user ID.
3807                } else {
3808                    if (UserHandle.getAppId(app.uid) != appId) {
3809                        continue;
3810                    }
3811                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3812                        continue;
3813                    }
3814                    if (!app.pkgList.contains(packageName)) {
3815                        continue;
3816                    }
3817                }
3818
3819                // Process has passed all conditions, kill it!
3820                if (!doit) {
3821                    return true;
3822                }
3823                app.removed = true;
3824                procs.add(app);
3825            }
3826        }
3827
3828        int N = procs.size();
3829        for (int i=0; i<N; i++) {
3830            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3831        }
3832        return N > 0;
3833    }
3834
3835    private final boolean forceStopPackageLocked(String name, int appId,
3836            boolean callerWillRestart, boolean purgeCache, boolean doit,
3837            boolean evenPersistent, int userId) {
3838        int i;
3839        int N;
3840
3841        if (userId == UserHandle.USER_ALL && name == null) {
3842            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3843        }
3844
3845        if (appId < 0 && name != null) {
3846            try {
3847                appId = UserHandle.getAppId(
3848                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3849            } catch (RemoteException e) {
3850            }
3851        }
3852
3853        if (doit) {
3854            if (name != null) {
3855                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3856                        + " user=" + userId);
3857            } else {
3858                Slog.i(TAG, "Force stopping user " + userId);
3859            }
3860
3861            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3862            while (badApps.hasNext()) {
3863                SparseArray<Long> ba = badApps.next();
3864                for (i=ba.size()-1; i>=0; i--) {
3865                    boolean remove = false;
3866                    final int entUid = ba.keyAt(i);
3867                    if (name != null) {
3868                        if (userId == UserHandle.USER_ALL) {
3869                            if (UserHandle.getAppId(entUid) == appId) {
3870                                remove = true;
3871                            }
3872                        } else {
3873                            if (entUid == UserHandle.getUid(userId, appId)) {
3874                                remove = true;
3875                            }
3876                        }
3877                    } else if (UserHandle.getUserId(entUid) == userId) {
3878                        remove = true;
3879                    }
3880                    if (remove) {
3881                        ba.removeAt(i);
3882                    }
3883                }
3884                if (ba.size() == 0) {
3885                    badApps.remove();
3886                }
3887            }
3888        }
3889
3890        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3891                -100, callerWillRestart, false, doit, evenPersistent,
3892                name == null ? ("force stop user " + userId) : ("force stop " + name));
3893
3894        TaskRecord lastTask = null;
3895        for (i=0; i<mMainStack.mHistory.size(); i++) {
3896            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3897            final boolean samePackage = r.packageName.equals(name)
3898                    || (name == null && r.userId == userId);
3899            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3900                    && (samePackage || r.task == lastTask)
3901                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3902                if (!doit) {
3903                    if (r.finishing) {
3904                        // If this activity is just finishing, then it is not
3905                        // interesting as far as something to stop.
3906                        continue;
3907                    }
3908                    return true;
3909                }
3910                didSomething = true;
3911                Slog.i(TAG, "  Force finishing activity " + r);
3912                if (samePackage) {
3913                    if (r.app != null) {
3914                        r.app.removed = true;
3915                    }
3916                    r.app = null;
3917                }
3918                lastTask = r.task;
3919                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3920                        null, "force-stop", true)) {
3921                    i--;
3922                }
3923            }
3924        }
3925
3926        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3927            if (!doit) {
3928                return true;
3929            }
3930            didSomething = true;
3931        }
3932
3933        if (name == null) {
3934            // Remove all sticky broadcasts from this user.
3935            mStickyBroadcasts.remove(userId);
3936        }
3937
3938        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3939        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3940                userId, providers)) {
3941            if (!doit) {
3942                return true;
3943            }
3944            didSomething = true;
3945        }
3946        N = providers.size();
3947        for (i=0; i<N; i++) {
3948            removeDyingProviderLocked(null, providers.get(i), true);
3949        }
3950
3951        if (mIntentSenderRecords.size() > 0) {
3952            Iterator<WeakReference<PendingIntentRecord>> it
3953                    = mIntentSenderRecords.values().iterator();
3954            while (it.hasNext()) {
3955                WeakReference<PendingIntentRecord> wpir = it.next();
3956                if (wpir == null) {
3957                    it.remove();
3958                    continue;
3959                }
3960                PendingIntentRecord pir = wpir.get();
3961                if (pir == null) {
3962                    it.remove();
3963                    continue;
3964                }
3965                if (name == null) {
3966                    // Stopping user, remove all objects for the user.
3967                    if (pir.key.userId != userId) {
3968                        // Not the same user, skip it.
3969                        continue;
3970                    }
3971                } else {
3972                    if (UserHandle.getAppId(pir.uid) != appId) {
3973                        // Different app id, skip it.
3974                        continue;
3975                    }
3976                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3977                        // Different user, skip it.
3978                        continue;
3979                    }
3980                    if (!pir.key.packageName.equals(name)) {
3981                        // Different package, skip it.
3982                        continue;
3983                    }
3984                }
3985                if (!doit) {
3986                    return true;
3987                }
3988                didSomething = true;
3989                it.remove();
3990                pir.canceled = true;
3991                if (pir.key.activity != null) {
3992                    pir.key.activity.pendingResults.remove(pir.ref);
3993                }
3994            }
3995        }
3996
3997        if (doit) {
3998            if (purgeCache && name != null) {
3999                AttributeCache ac = AttributeCache.instance();
4000                if (ac != null) {
4001                    ac.removePackage(name);
4002                }
4003            }
4004            if (mBooted) {
4005                mMainStack.resumeTopActivityLocked(null);
4006                mMainStack.scheduleIdleLocked();
4007            }
4008        }
4009
4010        return didSomething;
4011    }
4012
4013    private final boolean removeProcessLocked(ProcessRecord app,
4014            boolean callerWillRestart, boolean allowRestart, String reason) {
4015        final String name = app.processName;
4016        final int uid = app.uid;
4017        if (DEBUG_PROCESSES) Slog.d(
4018            TAG, "Force removing proc " + app.toShortString() + " (" + name
4019            + "/" + uid + ")");
4020
4021        mProcessNames.remove(name, uid);
4022        mIsolatedProcesses.remove(app.uid);
4023        if (mHeavyWeightProcess == app) {
4024            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4025                    mHeavyWeightProcess.userId, 0));
4026            mHeavyWeightProcess = null;
4027        }
4028        boolean needRestart = false;
4029        if (app.pid > 0 && app.pid != MY_PID) {
4030            int pid = app.pid;
4031            synchronized (mPidsSelfLocked) {
4032                mPidsSelfLocked.remove(pid);
4033                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4034            }
4035            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4036            handleAppDiedLocked(app, true, allowRestart);
4037            mLruProcesses.remove(app);
4038            Process.killProcessQuiet(pid);
4039
4040            if (app.persistent && !app.isolated) {
4041                if (!callerWillRestart) {
4042                    addAppLocked(app.info, false);
4043                } else {
4044                    needRestart = true;
4045                }
4046            }
4047        } else {
4048            mRemovedProcesses.add(app);
4049        }
4050
4051        return needRestart;
4052    }
4053
4054    private final void processStartTimedOutLocked(ProcessRecord app) {
4055        final int pid = app.pid;
4056        boolean gone = false;
4057        synchronized (mPidsSelfLocked) {
4058            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4059            if (knownApp != null && knownApp.thread == null) {
4060                mPidsSelfLocked.remove(pid);
4061                gone = true;
4062            }
4063        }
4064
4065        if (gone) {
4066            Slog.w(TAG, "Process " + app + " failed to attach");
4067            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4068                    app.processName);
4069            mProcessNames.remove(app.processName, app.uid);
4070            mIsolatedProcesses.remove(app.uid);
4071            if (mHeavyWeightProcess == app) {
4072                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4073                        mHeavyWeightProcess.userId, 0));
4074                mHeavyWeightProcess = null;
4075            }
4076            // Take care of any launching providers waiting for this process.
4077            checkAppInLaunchingProvidersLocked(app, true);
4078            // Take care of any services that are waiting for the process.
4079            mServices.processStartTimedOutLocked(app);
4080            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4081                    app.processName, app.setAdj, "start timeout");
4082            Process.killProcessQuiet(pid);
4083            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4084                Slog.w(TAG, "Unattached app died before backup, skipping");
4085                try {
4086                    IBackupManager bm = IBackupManager.Stub.asInterface(
4087                            ServiceManager.getService(Context.BACKUP_SERVICE));
4088                    bm.agentDisconnected(app.info.packageName);
4089                } catch (RemoteException e) {
4090                    // Can't happen; the backup manager is local
4091                }
4092            }
4093            if (isPendingBroadcastProcessLocked(pid)) {
4094                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4095                skipPendingBroadcastLocked(pid);
4096            }
4097        } else {
4098            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4099        }
4100    }
4101
4102    private final boolean attachApplicationLocked(IApplicationThread thread,
4103            int pid) {
4104
4105        // Find the application record that is being attached...  either via
4106        // the pid if we are running in multiple processes, or just pull the
4107        // next app record if we are emulating process with anonymous threads.
4108        ProcessRecord app;
4109        if (pid != MY_PID && pid >= 0) {
4110            synchronized (mPidsSelfLocked) {
4111                app = mPidsSelfLocked.get(pid);
4112            }
4113        } else {
4114            app = null;
4115        }
4116
4117        if (app == null) {
4118            Slog.w(TAG, "No pending application record for pid " + pid
4119                    + " (IApplicationThread " + thread + "); dropping process");
4120            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4121            if (pid > 0 && pid != MY_PID) {
4122                Process.killProcessQuiet(pid);
4123            } else {
4124                try {
4125                    thread.scheduleExit();
4126                } catch (Exception e) {
4127                    // Ignore exceptions.
4128                }
4129            }
4130            return false;
4131        }
4132
4133        // If this application record is still attached to a previous
4134        // process, clean it up now.
4135        if (app.thread != null) {
4136            handleAppDiedLocked(app, true, true);
4137        }
4138
4139        // Tell the process all about itself.
4140
4141        if (localLOGV) Slog.v(
4142                TAG, "Binding process pid " + pid + " to record " + app);
4143
4144        String processName = app.processName;
4145        try {
4146            AppDeathRecipient adr = new AppDeathRecipient(
4147                    app, pid, thread);
4148            thread.asBinder().linkToDeath(adr, 0);
4149            app.deathRecipient = adr;
4150        } catch (RemoteException e) {
4151            app.resetPackageList();
4152            startProcessLocked(app, "link fail", processName);
4153            return false;
4154        }
4155
4156        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4157
4158        app.thread = thread;
4159        app.curAdj = app.setAdj = -100;
4160        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4161        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4162        app.forcingToForeground = null;
4163        app.foregroundServices = false;
4164        app.hasShownUi = false;
4165        app.debugging = false;
4166
4167        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4168
4169        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4170        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4171
4172        if (!normalMode) {
4173            Slog.i(TAG, "Launching preboot mode app: " + app);
4174        }
4175
4176        if (localLOGV) Slog.v(
4177            TAG, "New app record " + app
4178            + " thread=" + thread.asBinder() + " pid=" + pid);
4179        try {
4180            int testMode = IApplicationThread.DEBUG_OFF;
4181            if (mDebugApp != null && mDebugApp.equals(processName)) {
4182                testMode = mWaitForDebugger
4183                    ? IApplicationThread.DEBUG_WAIT
4184                    : IApplicationThread.DEBUG_ON;
4185                app.debugging = true;
4186                if (mDebugTransient) {
4187                    mDebugApp = mOrigDebugApp;
4188                    mWaitForDebugger = mOrigWaitForDebugger;
4189                }
4190            }
4191            String profileFile = app.instrumentationProfileFile;
4192            ParcelFileDescriptor profileFd = null;
4193            boolean profileAutoStop = false;
4194            if (mProfileApp != null && mProfileApp.equals(processName)) {
4195                mProfileProc = app;
4196                profileFile = mProfileFile;
4197                profileFd = mProfileFd;
4198                profileAutoStop = mAutoStopProfiler;
4199            }
4200            boolean enableOpenGlTrace = false;
4201            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4202                enableOpenGlTrace = true;
4203                mOpenGlTraceApp = null;
4204            }
4205
4206            // If the app is being launched for restore or full backup, set it up specially
4207            boolean isRestrictedBackupMode = false;
4208            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4209                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4210                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4211                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4212            }
4213
4214            ensurePackageDexOpt(app.instrumentationInfo != null
4215                    ? app.instrumentationInfo.packageName
4216                    : app.info.packageName);
4217            if (app.instrumentationClass != null) {
4218                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4219            }
4220            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4221                    + processName + " with config " + mConfiguration);
4222            ApplicationInfo appInfo = app.instrumentationInfo != null
4223                    ? app.instrumentationInfo : app.info;
4224            app.compat = compatibilityInfoForPackageLocked(appInfo);
4225            if (profileFd != null) {
4226                profileFd = profileFd.dup();
4227            }
4228            thread.bindApplication(processName, appInfo, providers,
4229                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4230                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4231                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4232                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4233                    mCoreSettingsObserver.getCoreSettingsLocked());
4234            updateLruProcessLocked(app, false, true);
4235            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4236        } catch (Exception e) {
4237            // todo: Yikes!  What should we do?  For now we will try to
4238            // start another process, but that could easily get us in
4239            // an infinite loop of restarting processes...
4240            Slog.w(TAG, "Exception thrown during bind!", e);
4241
4242            app.resetPackageList();
4243            app.unlinkDeathRecipient();
4244            startProcessLocked(app, "bind fail", processName);
4245            return false;
4246        }
4247
4248        // Remove this record from the list of starting applications.
4249        mPersistentStartingProcesses.remove(app);
4250        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4251                "Attach application locked removing on hold: " + app);
4252        mProcessesOnHold.remove(app);
4253
4254        boolean badApp = false;
4255        boolean didSomething = false;
4256
4257        // See if the top visible activity is waiting to run in this process...
4258        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4259        if (hr != null && normalMode) {
4260            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4261                    && processName.equals(hr.processName)) {
4262                try {
4263                    if (mHeadless) {
4264                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4265                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4266                        didSomething = true;
4267                    }
4268                } catch (Exception e) {
4269                    Slog.w(TAG, "Exception in new application when starting activity "
4270                          + hr.intent.getComponent().flattenToShortString(), e);
4271                    badApp = true;
4272                }
4273            } else {
4274                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4275            }
4276        }
4277
4278        // Find any services that should be running in this process...
4279        if (!badApp) {
4280            try {
4281                didSomething |= mServices.attachApplicationLocked(app, processName);
4282            } catch (Exception e) {
4283                badApp = true;
4284            }
4285        }
4286
4287        // Check if a next-broadcast receiver is in this process...
4288        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4289            try {
4290                didSomething = sendPendingBroadcastsLocked(app);
4291            } catch (Exception e) {
4292                // If the app died trying to launch the receiver we declare it 'bad'
4293                badApp = true;
4294            }
4295        }
4296
4297        // Check whether the next backup agent is in this process...
4298        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4299            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4300            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4301            try {
4302                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4303                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4304                        mBackupTarget.backupMode);
4305            } catch (Exception e) {
4306                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4307                e.printStackTrace();
4308            }
4309        }
4310
4311        if (badApp) {
4312            // todo: Also need to kill application to deal with all
4313            // kinds of exceptions.
4314            handleAppDiedLocked(app, false, true);
4315            return false;
4316        }
4317
4318        if (!didSomething) {
4319            updateOomAdjLocked();
4320        }
4321
4322        return true;
4323    }
4324
4325    public final void attachApplication(IApplicationThread thread) {
4326        synchronized (this) {
4327            int callingPid = Binder.getCallingPid();
4328            final long origId = Binder.clearCallingIdentity();
4329            attachApplicationLocked(thread, callingPid);
4330            Binder.restoreCallingIdentity(origId);
4331        }
4332    }
4333
4334    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4335        final long origId = Binder.clearCallingIdentity();
4336        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4337        if (stopProfiling) {
4338            synchronized (this) {
4339                if (mProfileProc == r.app) {
4340                    if (mProfileFd != null) {
4341                        try {
4342                            mProfileFd.close();
4343                        } catch (IOException e) {
4344                        }
4345                        clearProfilerLocked();
4346                    }
4347                }
4348            }
4349        }
4350        Binder.restoreCallingIdentity(origId);
4351    }
4352
4353    void enableScreenAfterBoot() {
4354        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4355                SystemClock.uptimeMillis());
4356        mWindowManager.enableScreenAfterBoot();
4357
4358        synchronized (this) {
4359            updateEventDispatchingLocked();
4360        }
4361    }
4362
4363    public void showBootMessage(final CharSequence msg, final boolean always) {
4364        enforceNotIsolatedCaller("showBootMessage");
4365        mWindowManager.showBootMessage(msg, always);
4366    }
4367
4368    public void dismissKeyguardOnNextActivity() {
4369        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4370        final long token = Binder.clearCallingIdentity();
4371        try {
4372            synchronized (this) {
4373                if (mLockScreenShown) {
4374                    mLockScreenShown = false;
4375                    comeOutOfSleepIfNeededLocked();
4376                }
4377                mMainStack.dismissKeyguardOnNextActivityLocked();
4378            }
4379        } finally {
4380            Binder.restoreCallingIdentity(token);
4381        }
4382    }
4383
4384    final void finishBooting() {
4385        IntentFilter pkgFilter = new IntentFilter();
4386        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4387        pkgFilter.addDataScheme("package");
4388        mContext.registerReceiver(new BroadcastReceiver() {
4389            @Override
4390            public void onReceive(Context context, Intent intent) {
4391                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4392                if (pkgs != null) {
4393                    for (String pkg : pkgs) {
4394                        synchronized (ActivityManagerService.this) {
4395                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4396                                setResultCode(Activity.RESULT_OK);
4397                                return;
4398                            }
4399                        }
4400                    }
4401                }
4402            }
4403        }, pkgFilter);
4404
4405        synchronized (this) {
4406            // Ensure that any processes we had put on hold are now started
4407            // up.
4408            final int NP = mProcessesOnHold.size();
4409            if (NP > 0) {
4410                ArrayList<ProcessRecord> procs =
4411                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4412                for (int ip=0; ip<NP; ip++) {
4413                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4414                            + procs.get(ip));
4415                    startProcessLocked(procs.get(ip), "on-hold", null);
4416                }
4417            }
4418
4419            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4420                // Start looking for apps that are abusing wake locks.
4421                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4422                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4423                // Tell anyone interested that we are done booting!
4424                SystemProperties.set("sys.boot_completed", "1");
4425                SystemProperties.set("dev.bootcomplete", "1");
4426                for (int i=0; i<mStartedUsers.size(); i++) {
4427                    UserStartedState uss = mStartedUsers.valueAt(i);
4428                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4429                        uss.mState = UserStartedState.STATE_RUNNING;
4430                        final int userId = mStartedUsers.keyAt(i);
4431                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4432                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4433                        broadcastIntentLocked(null, null, intent,
4434                                null, null, 0, null, null,
4435                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4436                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4437                    }
4438                }
4439            }
4440        }
4441    }
4442
4443    final void ensureBootCompleted() {
4444        boolean booting;
4445        boolean enableScreen;
4446        synchronized (this) {
4447            booting = mBooting;
4448            mBooting = false;
4449            enableScreen = !mBooted;
4450            mBooted = true;
4451        }
4452
4453        if (booting) {
4454            finishBooting();
4455        }
4456
4457        if (enableScreen) {
4458            enableScreenAfterBoot();
4459        }
4460    }
4461
4462    public final void activityResumed(IBinder token) {
4463        final long origId = Binder.clearCallingIdentity();
4464        mMainStack.activityResumed(token);
4465        Binder.restoreCallingIdentity(origId);
4466    }
4467
4468    public final void activityPaused(IBinder token) {
4469        final long origId = Binder.clearCallingIdentity();
4470        mMainStack.activityPaused(token, false);
4471        Binder.restoreCallingIdentity(origId);
4472    }
4473
4474    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4475            CharSequence description) {
4476        if (localLOGV) Slog.v(
4477            TAG, "Activity stopped: token=" + token);
4478
4479        // Refuse possible leaked file descriptors
4480        if (icicle != null && icicle.hasFileDescriptors()) {
4481            throw new IllegalArgumentException("File descriptors passed in Bundle");
4482        }
4483
4484        ActivityRecord r = null;
4485
4486        final long origId = Binder.clearCallingIdentity();
4487
4488        synchronized (this) {
4489            r = mMainStack.isInStackLocked(token);
4490            if (r != null) {
4491                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4492            }
4493        }
4494
4495        if (r != null) {
4496            sendPendingThumbnail(r, null, null, null, false);
4497        }
4498
4499        trimApplications();
4500
4501        Binder.restoreCallingIdentity(origId);
4502    }
4503
4504    public final void activityDestroyed(IBinder token) {
4505        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4506        mMainStack.activityDestroyed(token);
4507    }
4508
4509    public String getCallingPackage(IBinder token) {
4510        synchronized (this) {
4511            ActivityRecord r = getCallingRecordLocked(token);
4512            return r != null && r.app != null ? r.info.packageName : null;
4513        }
4514    }
4515
4516    public ComponentName getCallingActivity(IBinder token) {
4517        synchronized (this) {
4518            ActivityRecord r = getCallingRecordLocked(token);
4519            return r != null ? r.intent.getComponent() : null;
4520        }
4521    }
4522
4523    private ActivityRecord getCallingRecordLocked(IBinder token) {
4524        ActivityRecord r = mMainStack.isInStackLocked(token);
4525        if (r == null) {
4526            return null;
4527        }
4528        return r.resultTo;
4529    }
4530
4531    public ComponentName getActivityClassForToken(IBinder token) {
4532        synchronized(this) {
4533            ActivityRecord r = mMainStack.isInStackLocked(token);
4534            if (r == null) {
4535                return null;
4536            }
4537            return r.intent.getComponent();
4538        }
4539    }
4540
4541    public String getPackageForToken(IBinder token) {
4542        synchronized(this) {
4543            ActivityRecord r = mMainStack.isInStackLocked(token);
4544            if (r == null) {
4545                return null;
4546            }
4547            return r.packageName;
4548        }
4549    }
4550
4551    public IIntentSender getIntentSender(int type,
4552            String packageName, IBinder token, String resultWho,
4553            int requestCode, Intent[] intents, String[] resolvedTypes,
4554            int flags, Bundle options, int userId) {
4555        enforceNotIsolatedCaller("getIntentSender");
4556        // Refuse possible leaked file descriptors
4557        if (intents != null) {
4558            if (intents.length < 1) {
4559                throw new IllegalArgumentException("Intents array length must be >= 1");
4560            }
4561            for (int i=0; i<intents.length; i++) {
4562                Intent intent = intents[i];
4563                if (intent != null) {
4564                    if (intent.hasFileDescriptors()) {
4565                        throw new IllegalArgumentException("File descriptors passed in Intent");
4566                    }
4567                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4568                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4569                        throw new IllegalArgumentException(
4570                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4571                    }
4572                    intents[i] = new Intent(intent);
4573                }
4574            }
4575            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4576                throw new IllegalArgumentException(
4577                        "Intent array length does not match resolvedTypes length");
4578            }
4579        }
4580        if (options != null) {
4581            if (options.hasFileDescriptors()) {
4582                throw new IllegalArgumentException("File descriptors passed in options");
4583            }
4584        }
4585
4586        synchronized(this) {
4587            int callingUid = Binder.getCallingUid();
4588            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4589                    false, true, "getIntentSender", null);
4590            try {
4591                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4592                    int uid = AppGlobals.getPackageManager()
4593                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4594                    if (!UserHandle.isSameApp(callingUid, uid)) {
4595                        String msg = "Permission Denial: getIntentSender() from pid="
4596                            + Binder.getCallingPid()
4597                            + ", uid=" + Binder.getCallingUid()
4598                            + ", (need uid=" + uid + ")"
4599                            + " is not allowed to send as package " + packageName;
4600                        Slog.w(TAG, msg);
4601                        throw new SecurityException(msg);
4602                    }
4603                }
4604
4605                return getIntentSenderLocked(type, packageName, callingUid, userId,
4606                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4607
4608            } catch (RemoteException e) {
4609                throw new SecurityException(e);
4610            }
4611        }
4612    }
4613
4614    IIntentSender getIntentSenderLocked(int type, String packageName,
4615            int callingUid, int userId, IBinder token, String resultWho,
4616            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4617            Bundle options) {
4618        if (DEBUG_MU)
4619            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4620        ActivityRecord activity = null;
4621        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4622            activity = mMainStack.isInStackLocked(token);
4623            if (activity == null) {
4624                return null;
4625            }
4626            if (activity.finishing) {
4627                return null;
4628            }
4629        }
4630
4631        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4632        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4633        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4634        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4635                |PendingIntent.FLAG_UPDATE_CURRENT);
4636
4637        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4638                type, packageName, activity, resultWho,
4639                requestCode, intents, resolvedTypes, flags, options, userId);
4640        WeakReference<PendingIntentRecord> ref;
4641        ref = mIntentSenderRecords.get(key);
4642        PendingIntentRecord rec = ref != null ? ref.get() : null;
4643        if (rec != null) {
4644            if (!cancelCurrent) {
4645                if (updateCurrent) {
4646                    if (rec.key.requestIntent != null) {
4647                        rec.key.requestIntent.replaceExtras(intents != null ?
4648                                intents[intents.length - 1] : null);
4649                    }
4650                    if (intents != null) {
4651                        intents[intents.length-1] = rec.key.requestIntent;
4652                        rec.key.allIntents = intents;
4653                        rec.key.allResolvedTypes = resolvedTypes;
4654                    } else {
4655                        rec.key.allIntents = null;
4656                        rec.key.allResolvedTypes = null;
4657                    }
4658                }
4659                return rec;
4660            }
4661            rec.canceled = true;
4662            mIntentSenderRecords.remove(key);
4663        }
4664        if (noCreate) {
4665            return rec;
4666        }
4667        rec = new PendingIntentRecord(this, key, callingUid);
4668        mIntentSenderRecords.put(key, rec.ref);
4669        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4670            if (activity.pendingResults == null) {
4671                activity.pendingResults
4672                        = new HashSet<WeakReference<PendingIntentRecord>>();
4673            }
4674            activity.pendingResults.add(rec.ref);
4675        }
4676        return rec;
4677    }
4678
4679    public void cancelIntentSender(IIntentSender sender) {
4680        if (!(sender instanceof PendingIntentRecord)) {
4681            return;
4682        }
4683        synchronized(this) {
4684            PendingIntentRecord rec = (PendingIntentRecord)sender;
4685            try {
4686                int uid = AppGlobals.getPackageManager()
4687                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4688                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4689                    String msg = "Permission Denial: cancelIntentSender() from pid="
4690                        + Binder.getCallingPid()
4691                        + ", uid=" + Binder.getCallingUid()
4692                        + " is not allowed to cancel packges "
4693                        + rec.key.packageName;
4694                    Slog.w(TAG, msg);
4695                    throw new SecurityException(msg);
4696                }
4697            } catch (RemoteException e) {
4698                throw new SecurityException(e);
4699            }
4700            cancelIntentSenderLocked(rec, true);
4701        }
4702    }
4703
4704    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4705        rec.canceled = true;
4706        mIntentSenderRecords.remove(rec.key);
4707        if (cleanActivity && rec.key.activity != null) {
4708            rec.key.activity.pendingResults.remove(rec.ref);
4709        }
4710    }
4711
4712    public String getPackageForIntentSender(IIntentSender pendingResult) {
4713        if (!(pendingResult instanceof PendingIntentRecord)) {
4714            return null;
4715        }
4716        try {
4717            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4718            return res.key.packageName;
4719        } catch (ClassCastException e) {
4720        }
4721        return null;
4722    }
4723
4724    public int getUidForIntentSender(IIntentSender sender) {
4725        if (sender instanceof PendingIntentRecord) {
4726            try {
4727                PendingIntentRecord res = (PendingIntentRecord)sender;
4728                return res.uid;
4729            } catch (ClassCastException e) {
4730            }
4731        }
4732        return -1;
4733    }
4734
4735    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4736        if (!(pendingResult instanceof PendingIntentRecord)) {
4737            return false;
4738        }
4739        try {
4740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4741            if (res.key.allIntents == null) {
4742                return false;
4743            }
4744            for (int i=0; i<res.key.allIntents.length; i++) {
4745                Intent intent = res.key.allIntents[i];
4746                if (intent.getPackage() != null && intent.getComponent() != null) {
4747                    return false;
4748                }
4749            }
4750            return true;
4751        } catch (ClassCastException e) {
4752        }
4753        return false;
4754    }
4755
4756    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4757        if (!(pendingResult instanceof PendingIntentRecord)) {
4758            return false;
4759        }
4760        try {
4761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4762            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4763                return true;
4764            }
4765            return false;
4766        } catch (ClassCastException e) {
4767        }
4768        return false;
4769    }
4770
4771    public void setProcessLimit(int max) {
4772        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4773                "setProcessLimit()");
4774        synchronized (this) {
4775            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4776            mProcessLimitOverride = max;
4777        }
4778        trimApplications();
4779    }
4780
4781    public int getProcessLimit() {
4782        synchronized (this) {
4783            return mProcessLimitOverride;
4784        }
4785    }
4786
4787    void foregroundTokenDied(ForegroundToken token) {
4788        synchronized (ActivityManagerService.this) {
4789            synchronized (mPidsSelfLocked) {
4790                ForegroundToken cur
4791                    = mForegroundProcesses.get(token.pid);
4792                if (cur != token) {
4793                    return;
4794                }
4795                mForegroundProcesses.remove(token.pid);
4796                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4797                if (pr == null) {
4798                    return;
4799                }
4800                pr.forcingToForeground = null;
4801                pr.foregroundServices = false;
4802            }
4803            updateOomAdjLocked();
4804        }
4805    }
4806
4807    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4808        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4809                "setProcessForeground()");
4810        synchronized(this) {
4811            boolean changed = false;
4812
4813            synchronized (mPidsSelfLocked) {
4814                ProcessRecord pr = mPidsSelfLocked.get(pid);
4815                if (pr == null && isForeground) {
4816                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4817                    return;
4818                }
4819                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4820                if (oldToken != null) {
4821                    oldToken.token.unlinkToDeath(oldToken, 0);
4822                    mForegroundProcesses.remove(pid);
4823                    if (pr != null) {
4824                        pr.forcingToForeground = null;
4825                    }
4826                    changed = true;
4827                }
4828                if (isForeground && token != null) {
4829                    ForegroundToken newToken = new ForegroundToken() {
4830                        public void binderDied() {
4831                            foregroundTokenDied(this);
4832                        }
4833                    };
4834                    newToken.pid = pid;
4835                    newToken.token = token;
4836                    try {
4837                        token.linkToDeath(newToken, 0);
4838                        mForegroundProcesses.put(pid, newToken);
4839                        pr.forcingToForeground = token;
4840                        changed = true;
4841                    } catch (RemoteException e) {
4842                        // If the process died while doing this, we will later
4843                        // do the cleanup with the process death link.
4844                    }
4845                }
4846            }
4847
4848            if (changed) {
4849                updateOomAdjLocked();
4850            }
4851        }
4852    }
4853
4854    // =========================================================
4855    // PERMISSIONS
4856    // =========================================================
4857
4858    static class PermissionController extends IPermissionController.Stub {
4859        ActivityManagerService mActivityManagerService;
4860        PermissionController(ActivityManagerService activityManagerService) {
4861            mActivityManagerService = activityManagerService;
4862        }
4863
4864        public boolean checkPermission(String permission, int pid, int uid) {
4865            return mActivityManagerService.checkPermission(permission, pid,
4866                    uid) == PackageManager.PERMISSION_GRANTED;
4867        }
4868    }
4869
4870    /**
4871     * This can be called with or without the global lock held.
4872     */
4873    int checkComponentPermission(String permission, int pid, int uid,
4874            int owningUid, boolean exported) {
4875        // We might be performing an operation on behalf of an indirect binder
4876        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4877        // client identity accordingly before proceeding.
4878        Identity tlsIdentity = sCallerIdentity.get();
4879        if (tlsIdentity != null) {
4880            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4881                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4882            uid = tlsIdentity.uid;
4883            pid = tlsIdentity.pid;
4884        }
4885
4886        if (pid == MY_PID) {
4887            return PackageManager.PERMISSION_GRANTED;
4888        }
4889
4890        return ActivityManager.checkComponentPermission(permission, uid,
4891                owningUid, exported);
4892    }
4893
4894    /**
4895     * As the only public entry point for permissions checking, this method
4896     * can enforce the semantic that requesting a check on a null global
4897     * permission is automatically denied.  (Internally a null permission
4898     * string is used when calling {@link #checkComponentPermission} in cases
4899     * when only uid-based security is needed.)
4900     *
4901     * This can be called with or without the global lock held.
4902     */
4903    public int checkPermission(String permission, int pid, int uid) {
4904        if (permission == null) {
4905            return PackageManager.PERMISSION_DENIED;
4906        }
4907        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4908    }
4909
4910    /**
4911     * Binder IPC calls go through the public entry point.
4912     * This can be called with or without the global lock held.
4913     */
4914    int checkCallingPermission(String permission) {
4915        return checkPermission(permission,
4916                Binder.getCallingPid(),
4917                UserHandle.getAppId(Binder.getCallingUid()));
4918    }
4919
4920    /**
4921     * This can be called with or without the global lock held.
4922     */
4923    void enforceCallingPermission(String permission, String func) {
4924        if (checkCallingPermission(permission)
4925                == PackageManager.PERMISSION_GRANTED) {
4926            return;
4927        }
4928
4929        String msg = "Permission Denial: " + func + " from pid="
4930                + Binder.getCallingPid()
4931                + ", uid=" + Binder.getCallingUid()
4932                + " requires " + permission;
4933        Slog.w(TAG, msg);
4934        throw new SecurityException(msg);
4935    }
4936
4937    /**
4938     * Determine if UID is holding permissions required to access {@link Uri} in
4939     * the given {@link ProviderInfo}. Final permission checking is always done
4940     * in {@link ContentProvider}.
4941     */
4942    private final boolean checkHoldingPermissionsLocked(
4943            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4944        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4945                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4946
4947        if (pi.applicationInfo.uid == uid) {
4948            return true;
4949        } else if (!pi.exported) {
4950            return false;
4951        }
4952
4953        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4954        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4955        try {
4956            // check if target holds top-level <provider> permissions
4957            if (!readMet && pi.readPermission != null
4958                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4959                readMet = true;
4960            }
4961            if (!writeMet && pi.writePermission != null
4962                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4963                writeMet = true;
4964            }
4965
4966            // track if unprotected read/write is allowed; any denied
4967            // <path-permission> below removes this ability
4968            boolean allowDefaultRead = pi.readPermission == null;
4969            boolean allowDefaultWrite = pi.writePermission == null;
4970
4971            // check if target holds any <path-permission> that match uri
4972            final PathPermission[] pps = pi.pathPermissions;
4973            if (pps != null) {
4974                final String path = uri.getPath();
4975                int i = pps.length;
4976                while (i > 0 && (!readMet || !writeMet)) {
4977                    i--;
4978                    PathPermission pp = pps[i];
4979                    if (pp.match(path)) {
4980                        if (!readMet) {
4981                            final String pprperm = pp.getReadPermission();
4982                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4983                                    + pprperm + " for " + pp.getPath()
4984                                    + ": match=" + pp.match(path)
4985                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4986                            if (pprperm != null) {
4987                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4988                                    readMet = true;
4989                                } else {
4990                                    allowDefaultRead = false;
4991                                }
4992                            }
4993                        }
4994                        if (!writeMet) {
4995                            final String ppwperm = pp.getWritePermission();
4996                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4997                                    + ppwperm + " for " + pp.getPath()
4998                                    + ": match=" + pp.match(path)
4999                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5000                            if (ppwperm != null) {
5001                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5002                                    writeMet = true;
5003                                } else {
5004                                    allowDefaultWrite = false;
5005                                }
5006                            }
5007                        }
5008                    }
5009                }
5010            }
5011
5012            // grant unprotected <provider> read/write, if not blocked by
5013            // <path-permission> above
5014            if (allowDefaultRead) readMet = true;
5015            if (allowDefaultWrite) writeMet = true;
5016
5017        } catch (RemoteException e) {
5018            return false;
5019        }
5020
5021        return readMet && writeMet;
5022    }
5023
5024    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5025            int modeFlags) {
5026        // Root gets to do everything.
5027        if (uid == 0) {
5028            return true;
5029        }
5030        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5031        if (perms == null) return false;
5032        UriPermission perm = perms.get(uri);
5033        if (perm == null) return false;
5034        return (modeFlags&perm.modeFlags) == modeFlags;
5035    }
5036
5037    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5038        enforceNotIsolatedCaller("checkUriPermission");
5039
5040        // Another redirected-binder-call permissions check as in
5041        // {@link checkComponentPermission}.
5042        Identity tlsIdentity = sCallerIdentity.get();
5043        if (tlsIdentity != null) {
5044            uid = tlsIdentity.uid;
5045            pid = tlsIdentity.pid;
5046        }
5047
5048        // Our own process gets to do everything.
5049        if (pid == MY_PID) {
5050            return PackageManager.PERMISSION_GRANTED;
5051        }
5052        synchronized(this) {
5053            return checkUriPermissionLocked(uri, uid, modeFlags)
5054                    ? PackageManager.PERMISSION_GRANTED
5055                    : PackageManager.PERMISSION_DENIED;
5056        }
5057    }
5058
5059    /**
5060     * Check if the targetPkg can be granted permission to access uri by
5061     * the callingUid using the given modeFlags.  Throws a security exception
5062     * if callingUid is not allowed to do this.  Returns the uid of the target
5063     * if the URI permission grant should be performed; returns -1 if it is not
5064     * needed (for example targetPkg already has permission to access the URI).
5065     * If you already know the uid of the target, you can supply it in
5066     * lastTargetUid else set that to -1.
5067     */
5068    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5069            Uri uri, int modeFlags, int lastTargetUid) {
5070        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5071                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5072        if (modeFlags == 0) {
5073            return -1;
5074        }
5075
5076        if (targetPkg != null) {
5077            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5078                    "Checking grant " + targetPkg + " permission to " + uri);
5079        }
5080
5081        final IPackageManager pm = AppGlobals.getPackageManager();
5082
5083        // If this is not a content: uri, we can't do anything with it.
5084        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5085            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5086                    "Can't grant URI permission for non-content URI: " + uri);
5087            return -1;
5088        }
5089
5090        String name = uri.getAuthority();
5091        ProviderInfo pi = null;
5092        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5093                UserHandle.getUserId(callingUid));
5094        if (cpr != null) {
5095            pi = cpr.info;
5096        } else {
5097            try {
5098                pi = pm.resolveContentProvider(name,
5099                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5100                        UserHandle.getUserId(callingUid));
5101            } catch (RemoteException ex) {
5102            }
5103        }
5104        if (pi == null) {
5105            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5106            return -1;
5107        }
5108
5109        int targetUid = lastTargetUid;
5110        if (targetUid < 0 && targetPkg != null) {
5111            try {
5112                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5113                if (targetUid < 0) {
5114                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5115                            "Can't grant URI permission no uid for: " + targetPkg);
5116                    return -1;
5117                }
5118            } catch (RemoteException ex) {
5119                return -1;
5120            }
5121        }
5122
5123        if (targetUid >= 0) {
5124            // First...  does the target actually need this permission?
5125            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5126                // No need to grant the target this permission.
5127                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5128                        "Target " + targetPkg + " already has full permission to " + uri);
5129                return -1;
5130            }
5131        } else {
5132            // First...  there is no target package, so can anyone access it?
5133            boolean allowed = pi.exported;
5134            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5135                if (pi.readPermission != null) {
5136                    allowed = false;
5137                }
5138            }
5139            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5140                if (pi.writePermission != null) {
5141                    allowed = false;
5142                }
5143            }
5144            if (allowed) {
5145                return -1;
5146            }
5147        }
5148
5149        // Second...  is the provider allowing granting of URI permissions?
5150        if (!pi.grantUriPermissions) {
5151            throw new SecurityException("Provider " + pi.packageName
5152                    + "/" + pi.name
5153                    + " does not allow granting of Uri permissions (uri "
5154                    + uri + ")");
5155        }
5156        if (pi.uriPermissionPatterns != null) {
5157            final int N = pi.uriPermissionPatterns.length;
5158            boolean allowed = false;
5159            for (int i=0; i<N; i++) {
5160                if (pi.uriPermissionPatterns[i] != null
5161                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5162                    allowed = true;
5163                    break;
5164                }
5165            }
5166            if (!allowed) {
5167                throw new SecurityException("Provider " + pi.packageName
5168                        + "/" + pi.name
5169                        + " does not allow granting of permission to path of Uri "
5170                        + uri);
5171            }
5172        }
5173
5174        // Third...  does the caller itself have permission to access
5175        // this uri?
5176        if (callingUid != Process.myUid()) {
5177            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5178                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5179                    throw new SecurityException("Uid " + callingUid
5180                            + " does not have permission to uri " + uri);
5181                }
5182            }
5183        }
5184
5185        return targetUid;
5186    }
5187
5188    public int checkGrantUriPermission(int callingUid, String targetPkg,
5189            Uri uri, int modeFlags) {
5190        enforceNotIsolatedCaller("checkGrantUriPermission");
5191        synchronized(this) {
5192            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5193        }
5194    }
5195
5196    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5197            Uri uri, int modeFlags, UriPermissionOwner owner) {
5198        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5199                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5200        if (modeFlags == 0) {
5201            return;
5202        }
5203
5204        // So here we are: the caller has the assumed permission
5205        // to the uri, and the target doesn't.  Let's now give this to
5206        // the target.
5207
5208        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5209                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5210
5211        HashMap<Uri, UriPermission> targetUris
5212                = mGrantedUriPermissions.get(targetUid);
5213        if (targetUris == null) {
5214            targetUris = new HashMap<Uri, UriPermission>();
5215            mGrantedUriPermissions.put(targetUid, targetUris);
5216        }
5217
5218        UriPermission perm = targetUris.get(uri);
5219        if (perm == null) {
5220            perm = new UriPermission(targetUid, uri);
5221            targetUris.put(uri, perm);
5222        }
5223
5224        perm.modeFlags |= modeFlags;
5225        if (owner == null) {
5226            perm.globalModeFlags |= modeFlags;
5227        } else {
5228            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5229                 perm.readOwners.add(owner);
5230                 owner.addReadPermission(perm);
5231            }
5232            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5233                 perm.writeOwners.add(owner);
5234                 owner.addWritePermission(perm);
5235            }
5236        }
5237    }
5238
5239    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5240            int modeFlags, UriPermissionOwner owner) {
5241        if (targetPkg == null) {
5242            throw new NullPointerException("targetPkg");
5243        }
5244
5245        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5246        if (targetUid < 0) {
5247            return;
5248        }
5249
5250        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5251    }
5252
5253    static class NeededUriGrants extends ArrayList<Uri> {
5254        final String targetPkg;
5255        final int targetUid;
5256        final int flags;
5257
5258        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5259            targetPkg = _targetPkg;
5260            targetUid = _targetUid;
5261            flags = _flags;
5262        }
5263    }
5264
5265    /**
5266     * Like checkGrantUriPermissionLocked, but takes an Intent.
5267     */
5268    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5269            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5270        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5271                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5272                + " clip=" + (intent != null ? intent.getClipData() : null)
5273                + " from " + intent + "; flags=0x"
5274                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5275
5276        if (targetPkg == null) {
5277            throw new NullPointerException("targetPkg");
5278        }
5279
5280        if (intent == null) {
5281            return null;
5282        }
5283        Uri data = intent.getData();
5284        ClipData clip = intent.getClipData();
5285        if (data == null && clip == null) {
5286            return null;
5287        }
5288        if (data != null) {
5289            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5290                mode, needed != null ? needed.targetUid : -1);
5291            if (target > 0) {
5292                if (needed == null) {
5293                    needed = new NeededUriGrants(targetPkg, target, mode);
5294                }
5295                needed.add(data);
5296            }
5297        }
5298        if (clip != null) {
5299            for (int i=0; i<clip.getItemCount(); i++) {
5300                Uri uri = clip.getItemAt(i).getUri();
5301                if (uri != null) {
5302                    int target = -1;
5303                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5304                            mode, needed != null ? needed.targetUid : -1);
5305                    if (target > 0) {
5306                        if (needed == null) {
5307                            needed = new NeededUriGrants(targetPkg, target, mode);
5308                        }
5309                        needed.add(uri);
5310                    }
5311                } else {
5312                    Intent clipIntent = clip.getItemAt(i).getIntent();
5313                    if (clipIntent != null) {
5314                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5315                                callingUid, targetPkg, clipIntent, mode, needed);
5316                        if (newNeeded != null) {
5317                            needed = newNeeded;
5318                        }
5319                    }
5320                }
5321            }
5322        }
5323
5324        return needed;
5325    }
5326
5327    /**
5328     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5329     */
5330    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5331            UriPermissionOwner owner) {
5332        if (needed != null) {
5333            for (int i=0; i<needed.size(); i++) {
5334                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5335                        needed.get(i), needed.flags, owner);
5336            }
5337        }
5338    }
5339
5340    void grantUriPermissionFromIntentLocked(int callingUid,
5341            String targetPkg, Intent intent, UriPermissionOwner owner) {
5342        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5343                intent, intent != null ? intent.getFlags() : 0, null);
5344        if (needed == null) {
5345            return;
5346        }
5347
5348        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5349    }
5350
5351    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5352            Uri uri, int modeFlags) {
5353        enforceNotIsolatedCaller("grantUriPermission");
5354        synchronized(this) {
5355            final ProcessRecord r = getRecordForAppLocked(caller);
5356            if (r == null) {
5357                throw new SecurityException("Unable to find app for caller "
5358                        + caller
5359                        + " when granting permission to uri " + uri);
5360            }
5361            if (targetPkg == null) {
5362                throw new IllegalArgumentException("null target");
5363            }
5364            if (uri == null) {
5365                throw new IllegalArgumentException("null uri");
5366            }
5367
5368            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5369                    null);
5370        }
5371    }
5372
5373    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5374        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5375                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5376            HashMap<Uri, UriPermission> perms
5377                    = mGrantedUriPermissions.get(perm.uid);
5378            if (perms != null) {
5379                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5380                        "Removing " + perm.uid + " permission to " + perm.uri);
5381                perms.remove(perm.uri);
5382                if (perms.size() == 0) {
5383                    mGrantedUriPermissions.remove(perm.uid);
5384                }
5385            }
5386        }
5387    }
5388
5389    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5390            int modeFlags) {
5391        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5392                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5393        if (modeFlags == 0) {
5394            return;
5395        }
5396
5397        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5398                "Revoking all granted permissions to " + uri);
5399
5400        final IPackageManager pm = AppGlobals.getPackageManager();
5401
5402        final String authority = uri.getAuthority();
5403        ProviderInfo pi = null;
5404        int userId = UserHandle.getUserId(callingUid);
5405        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5406        if (cpr != null) {
5407            pi = cpr.info;
5408        } else {
5409            try {
5410                pi = pm.resolveContentProvider(authority,
5411                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5412            } catch (RemoteException ex) {
5413            }
5414        }
5415        if (pi == null) {
5416            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5417            return;
5418        }
5419
5420        // Does the caller have this permission on the URI?
5421        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5422            // Right now, if you are not the original owner of the permission,
5423            // you are not allowed to revoke it.
5424            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5425                throw new SecurityException("Uid " + callingUid
5426                        + " does not have permission to uri " + uri);
5427            //}
5428        }
5429
5430        // Go through all of the permissions and remove any that match.
5431        final List<String> SEGMENTS = uri.getPathSegments();
5432        if (SEGMENTS != null) {
5433            final int NS = SEGMENTS.size();
5434            int N = mGrantedUriPermissions.size();
5435            for (int i=0; i<N; i++) {
5436                HashMap<Uri, UriPermission> perms
5437                        = mGrantedUriPermissions.valueAt(i);
5438                Iterator<UriPermission> it = perms.values().iterator();
5439            toploop:
5440                while (it.hasNext()) {
5441                    UriPermission perm = it.next();
5442                    Uri targetUri = perm.uri;
5443                    if (!authority.equals(targetUri.getAuthority())) {
5444                        continue;
5445                    }
5446                    List<String> targetSegments = targetUri.getPathSegments();
5447                    if (targetSegments == null) {
5448                        continue;
5449                    }
5450                    if (targetSegments.size() < NS) {
5451                        continue;
5452                    }
5453                    for (int j=0; j<NS; j++) {
5454                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5455                            continue toploop;
5456                        }
5457                    }
5458                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5459                            "Revoking " + perm.uid + " permission to " + perm.uri);
5460                    perm.clearModes(modeFlags);
5461                    if (perm.modeFlags == 0) {
5462                        it.remove();
5463                    }
5464                }
5465                if (perms.size() == 0) {
5466                    mGrantedUriPermissions.remove(
5467                            mGrantedUriPermissions.keyAt(i));
5468                    N--;
5469                    i--;
5470                }
5471            }
5472        }
5473    }
5474
5475    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5476            int modeFlags) {
5477        enforceNotIsolatedCaller("revokeUriPermission");
5478        synchronized(this) {
5479            final ProcessRecord r = getRecordForAppLocked(caller);
5480            if (r == null) {
5481                throw new SecurityException("Unable to find app for caller "
5482                        + caller
5483                        + " when revoking permission to uri " + uri);
5484            }
5485            if (uri == null) {
5486                Slog.w(TAG, "revokeUriPermission: null uri");
5487                return;
5488            }
5489
5490            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5491                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5492            if (modeFlags == 0) {
5493                return;
5494            }
5495
5496            final IPackageManager pm = AppGlobals.getPackageManager();
5497
5498            final String authority = uri.getAuthority();
5499            ProviderInfo pi = null;
5500            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5501            if (cpr != null) {
5502                pi = cpr.info;
5503            } else {
5504                try {
5505                    pi = pm.resolveContentProvider(authority,
5506                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5507                } catch (RemoteException ex) {
5508                }
5509            }
5510            if (pi == null) {
5511                Slog.w(TAG, "No content provider found for permission revoke: "
5512                        + uri.toSafeString());
5513                return;
5514            }
5515
5516            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5517        }
5518    }
5519
5520    @Override
5521    public IBinder newUriPermissionOwner(String name) {
5522        enforceNotIsolatedCaller("newUriPermissionOwner");
5523        synchronized(this) {
5524            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5525            return owner.getExternalTokenLocked();
5526        }
5527    }
5528
5529    @Override
5530    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5531            Uri uri, int modeFlags) {
5532        synchronized(this) {
5533            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5534            if (owner == null) {
5535                throw new IllegalArgumentException("Unknown owner: " + token);
5536            }
5537            if (fromUid != Binder.getCallingUid()) {
5538                if (Binder.getCallingUid() != Process.myUid()) {
5539                    // Only system code can grant URI permissions on behalf
5540                    // of other users.
5541                    throw new SecurityException("nice try");
5542                }
5543            }
5544            if (targetPkg == null) {
5545                throw new IllegalArgumentException("null target");
5546            }
5547            if (uri == null) {
5548                throw new IllegalArgumentException("null uri");
5549            }
5550
5551            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5552        }
5553    }
5554
5555    @Override
5556    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5557        synchronized(this) {
5558            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5559            if (owner == null) {
5560                throw new IllegalArgumentException("Unknown owner: " + token);
5561            }
5562
5563            if (uri == null) {
5564                owner.removeUriPermissionsLocked(mode);
5565            } else {
5566                owner.removeUriPermissionLocked(uri, mode);
5567            }
5568        }
5569    }
5570
5571    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5572        synchronized (this) {
5573            ProcessRecord app =
5574                who != null ? getRecordForAppLocked(who) : null;
5575            if (app == null) return;
5576
5577            Message msg = Message.obtain();
5578            msg.what = WAIT_FOR_DEBUGGER_MSG;
5579            msg.obj = app;
5580            msg.arg1 = waiting ? 1 : 0;
5581            mHandler.sendMessage(msg);
5582        }
5583    }
5584
5585    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5586        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5587        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5588        outInfo.availMem = Process.getFreeMemory();
5589        outInfo.totalMem = Process.getTotalMemory();
5590        outInfo.threshold = homeAppMem;
5591        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5592        outInfo.hiddenAppThreshold = hiddenAppMem;
5593        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5594                ProcessList.SERVICE_ADJ);
5595        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5596                ProcessList.VISIBLE_APP_ADJ);
5597        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5598                ProcessList.FOREGROUND_APP_ADJ);
5599    }
5600
5601    // =========================================================
5602    // TASK MANAGEMENT
5603    // =========================================================
5604
5605    public List getTasks(int maxNum, int flags,
5606                         IThumbnailReceiver receiver) {
5607        ArrayList list = new ArrayList();
5608
5609        PendingThumbnailsRecord pending = null;
5610        IApplicationThread topThumbnail = null;
5611        ActivityRecord topRecord = null;
5612
5613        synchronized(this) {
5614            if (localLOGV) Slog.v(
5615                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5616                + ", receiver=" + receiver);
5617
5618            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5619                    != PackageManager.PERMISSION_GRANTED) {
5620                if (receiver != null) {
5621                    // If the caller wants to wait for pending thumbnails,
5622                    // it ain't gonna get them.
5623                    try {
5624                        receiver.finished();
5625                    } catch (RemoteException ex) {
5626                    }
5627                }
5628                String msg = "Permission Denial: getTasks() from pid="
5629                        + Binder.getCallingPid()
5630                        + ", uid=" + Binder.getCallingUid()
5631                        + " requires " + android.Manifest.permission.GET_TASKS;
5632                Slog.w(TAG, msg);
5633                throw new SecurityException(msg);
5634            }
5635
5636            int pos = mMainStack.mHistory.size()-1;
5637            ActivityRecord next =
5638                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5639            ActivityRecord top = null;
5640            TaskRecord curTask = null;
5641            int numActivities = 0;
5642            int numRunning = 0;
5643            while (pos >= 0 && maxNum > 0) {
5644                final ActivityRecord r = next;
5645                pos--;
5646                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5647
5648                // Initialize state for next task if needed.
5649                if (top == null ||
5650                        (top.state == ActivityState.INITIALIZING
5651                            && top.task == r.task)) {
5652                    top = r;
5653                    curTask = r.task;
5654                    numActivities = numRunning = 0;
5655                }
5656
5657                // Add 'r' into the current task.
5658                numActivities++;
5659                if (r.app != null && r.app.thread != null) {
5660                    numRunning++;
5661                }
5662
5663                if (localLOGV) Slog.v(
5664                    TAG, r.intent.getComponent().flattenToShortString()
5665                    + ": task=" + r.task);
5666
5667                // If the next one is a different task, generate a new
5668                // TaskInfo entry for what we have.
5669                if (next == null || next.task != curTask) {
5670                    ActivityManager.RunningTaskInfo ci
5671                            = new ActivityManager.RunningTaskInfo();
5672                    ci.id = curTask.taskId;
5673                    ci.baseActivity = r.intent.getComponent();
5674                    ci.topActivity = top.intent.getComponent();
5675                    if (top.thumbHolder != null) {
5676                        ci.description = top.thumbHolder.lastDescription;
5677                    }
5678                    ci.numActivities = numActivities;
5679                    ci.numRunning = numRunning;
5680                    //System.out.println(
5681                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5682                    if (ci.thumbnail == null && receiver != null) {
5683                        if (localLOGV) Slog.v(
5684                            TAG, "State=" + top.state + "Idle=" + top.idle
5685                            + " app=" + top.app
5686                            + " thr=" + (top.app != null ? top.app.thread : null));
5687                        if (top.state == ActivityState.RESUMED
5688                                || top.state == ActivityState.PAUSING) {
5689                            if (top.idle && top.app != null
5690                                && top.app.thread != null) {
5691                                topRecord = top;
5692                                topThumbnail = top.app.thread;
5693                            } else {
5694                                top.thumbnailNeeded = true;
5695                            }
5696                        }
5697                        if (pending == null) {
5698                            pending = new PendingThumbnailsRecord(receiver);
5699                        }
5700                        pending.pendingRecords.add(top);
5701                    }
5702                    list.add(ci);
5703                    maxNum--;
5704                    top = null;
5705                }
5706            }
5707
5708            if (pending != null) {
5709                mPendingThumbnails.add(pending);
5710            }
5711        }
5712
5713        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5714
5715        if (topThumbnail != null) {
5716            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5717            try {
5718                topThumbnail.requestThumbnail(topRecord.appToken);
5719            } catch (Exception e) {
5720                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5721                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5722            }
5723        }
5724
5725        if (pending == null && receiver != null) {
5726            // In this case all thumbnails were available and the client
5727            // is being asked to be told when the remaining ones come in...
5728            // which is unusually, since the top-most currently running
5729            // activity should never have a canned thumbnail!  Oh well.
5730            try {
5731                receiver.finished();
5732            } catch (RemoteException ex) {
5733            }
5734        }
5735
5736        return list;
5737    }
5738
5739    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5740            int flags, int userId) {
5741        final int callingUid = Binder.getCallingUid();
5742        if (userId != UserHandle.getCallingUserId()) {
5743            // Check if the caller is holding permissions for cross-user requests.
5744            if (checkComponentPermission(
5745                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5746                    Binder.getCallingPid(), callingUid, -1, true)
5747                    != PackageManager.PERMISSION_GRANTED) {
5748                String msg = "Permission Denial: "
5749                        + "Request to get recent tasks for user " + userId
5750                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5751                        + "; this requires "
5752                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5753                Slog.w(TAG, msg);
5754                throw new SecurityException(msg);
5755            } else {
5756                if (userId == UserHandle.USER_CURRENT) {
5757                    userId = mCurrentUserId;
5758                }
5759            }
5760        }
5761
5762        synchronized (this) {
5763            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5764                    "getRecentTasks()");
5765            final boolean detailed = checkCallingPermission(
5766                    android.Manifest.permission.GET_DETAILED_TASKS)
5767                    == PackageManager.PERMISSION_GRANTED;
5768
5769            IPackageManager pm = AppGlobals.getPackageManager();
5770
5771            final int N = mRecentTasks.size();
5772            ArrayList<ActivityManager.RecentTaskInfo> res
5773                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5774                            maxNum < N ? maxNum : N);
5775            for (int i=0; i<N && maxNum > 0; i++) {
5776                TaskRecord tr = mRecentTasks.get(i);
5777                // Only add calling user's recent tasks
5778                if (tr.userId != userId) continue;
5779                // Return the entry if desired by the caller.  We always return
5780                // the first entry, because callers always expect this to be the
5781                // foreground app.  We may filter others if the caller has
5782                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5783                // we should exclude the entry.
5784
5785                if (i == 0
5786                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5787                        || (tr.intent == null)
5788                        || ((tr.intent.getFlags()
5789                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5790                    ActivityManager.RecentTaskInfo rti
5791                            = new ActivityManager.RecentTaskInfo();
5792                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5793                    rti.persistentId = tr.taskId;
5794                    rti.baseIntent = new Intent(
5795                            tr.intent != null ? tr.intent : tr.affinityIntent);
5796                    if (!detailed) {
5797                        rti.baseIntent.replaceExtras((Bundle)null);
5798                    }
5799                    rti.origActivity = tr.origActivity;
5800                    rti.description = tr.lastDescription;
5801
5802                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5803                        // Check whether this activity is currently available.
5804                        try {
5805                            if (rti.origActivity != null) {
5806                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5807                                        == null) {
5808                                    continue;
5809                                }
5810                            } else if (rti.baseIntent != null) {
5811                                if (pm.queryIntentActivities(rti.baseIntent,
5812                                        null, 0, userId) == null) {
5813                                    continue;
5814                                }
5815                            }
5816                        } catch (RemoteException e) {
5817                            // Will never happen.
5818                        }
5819                    }
5820
5821                    res.add(rti);
5822                    maxNum--;
5823                }
5824            }
5825            return res;
5826        }
5827    }
5828
5829    private TaskRecord taskForIdLocked(int id) {
5830        final int N = mRecentTasks.size();
5831        for (int i=0; i<N; i++) {
5832            TaskRecord tr = mRecentTasks.get(i);
5833            if (tr.taskId == id) {
5834                return tr;
5835            }
5836        }
5837        return null;
5838    }
5839
5840    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5841        synchronized (this) {
5842            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5843                    "getTaskThumbnails()");
5844            TaskRecord tr = taskForIdLocked(id);
5845            if (tr != null) {
5846                return mMainStack.getTaskThumbnailsLocked(tr);
5847            }
5848        }
5849        return null;
5850    }
5851
5852    public boolean removeSubTask(int taskId, int subTaskIndex) {
5853        synchronized (this) {
5854            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5855                    "removeSubTask()");
5856            long ident = Binder.clearCallingIdentity();
5857            try {
5858                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5859                        true) != null;
5860            } finally {
5861                Binder.restoreCallingIdentity(ident);
5862            }
5863        }
5864    }
5865
5866    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5867        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5868        Intent baseIntent = new Intent(
5869                tr.intent != null ? tr.intent : tr.affinityIntent);
5870        ComponentName component = baseIntent.getComponent();
5871        if (component == null) {
5872            Slog.w(TAG, "Now component for base intent of task: " + tr);
5873            return;
5874        }
5875
5876        // Find any running services associated with this app.
5877        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5878
5879        if (killProcesses) {
5880            // Find any running processes associated with this app.
5881            final String pkg = component.getPackageName();
5882            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5883            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5884            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5885                for (int i=0; i<uids.size(); i++) {
5886                    ProcessRecord proc = uids.valueAt(i);
5887                    if (proc.userId != tr.userId) {
5888                        continue;
5889                    }
5890                    if (!proc.pkgList.contains(pkg)) {
5891                        continue;
5892                    }
5893                    procs.add(proc);
5894                }
5895            }
5896
5897            // Kill the running processes.
5898            for (int i=0; i<procs.size(); i++) {
5899                ProcessRecord pr = procs.get(i);
5900                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5901                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5902                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5903                            pr.processName, pr.setAdj, "remove task");
5904                    pr.killedBackground = true;
5905                    Process.killProcessQuiet(pr.pid);
5906                } else {
5907                    pr.waitingToKill = "remove task";
5908                }
5909            }
5910        }
5911    }
5912
5913    public boolean removeTask(int taskId, int flags) {
5914        synchronized (this) {
5915            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5916                    "removeTask()");
5917            long ident = Binder.clearCallingIdentity();
5918            try {
5919                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5920                        false);
5921                if (r != null) {
5922                    mRecentTasks.remove(r.task);
5923                    cleanUpRemovedTaskLocked(r.task, flags);
5924                    return true;
5925                } else {
5926                    TaskRecord tr = null;
5927                    int i=0;
5928                    while (i < mRecentTasks.size()) {
5929                        TaskRecord t = mRecentTasks.get(i);
5930                        if (t.taskId == taskId) {
5931                            tr = t;
5932                            break;
5933                        }
5934                        i++;
5935                    }
5936                    if (tr != null) {
5937                        if (tr.numActivities <= 0) {
5938                            // Caller is just removing a recent task that is
5939                            // not actively running.  That is easy!
5940                            mRecentTasks.remove(i);
5941                            cleanUpRemovedTaskLocked(tr, flags);
5942                            return true;
5943                        } else {
5944                            Slog.w(TAG, "removeTask: task " + taskId
5945                                    + " does not have activities to remove, "
5946                                    + " but numActivities=" + tr.numActivities
5947                                    + ": " + tr);
5948                        }
5949                    }
5950                }
5951            } finally {
5952                Binder.restoreCallingIdentity(ident);
5953            }
5954        }
5955        return false;
5956    }
5957
5958    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5959        int j;
5960        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5961        TaskRecord jt = startTask;
5962
5963        // First look backwards
5964        for (j=startIndex-1; j>=0; j--) {
5965            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5966            if (r.task != jt) {
5967                jt = r.task;
5968                if (affinity.equals(jt.affinity)) {
5969                    return j;
5970                }
5971            }
5972        }
5973
5974        // Now look forwards
5975        final int N = mMainStack.mHistory.size();
5976        jt = startTask;
5977        for (j=startIndex+1; j<N; j++) {
5978            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5979            if (r.task != jt) {
5980                if (affinity.equals(jt.affinity)) {
5981                    return j;
5982                }
5983                jt = r.task;
5984            }
5985        }
5986
5987        // Might it be at the top?
5988        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5989            return N-1;
5990        }
5991
5992        return -1;
5993    }
5994
5995    /**
5996     * TODO: Add mController hook
5997     */
5998    public void moveTaskToFront(int task, int flags, Bundle options) {
5999        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6000                "moveTaskToFront()");
6001
6002        synchronized(this) {
6003            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6004                    Binder.getCallingUid(), "Task to front")) {
6005                ActivityOptions.abort(options);
6006                return;
6007            }
6008            final long origId = Binder.clearCallingIdentity();
6009            try {
6010                TaskRecord tr = taskForIdLocked(task);
6011                if (tr != null) {
6012                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6013                        mMainStack.mUserLeaving = true;
6014                    }
6015                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6016                        // Caller wants the home activity moved with it.  To accomplish this,
6017                        // we'll just move the home task to the top first.
6018                        mMainStack.moveHomeToFrontLocked();
6019                    }
6020                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6021                    return;
6022                }
6023                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6024                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6025                    if (hr.task.taskId == task) {
6026                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6027                            mMainStack.mUserLeaving = true;
6028                        }
6029                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6030                            // Caller wants the home activity moved with it.  To accomplish this,
6031                            // we'll just move the home task to the top first.
6032                            mMainStack.moveHomeToFrontLocked();
6033                        }
6034                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6035                        return;
6036                    }
6037                }
6038            } finally {
6039                Binder.restoreCallingIdentity(origId);
6040            }
6041            ActivityOptions.abort(options);
6042        }
6043    }
6044
6045    public void moveTaskToBack(int task) {
6046        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6047                "moveTaskToBack()");
6048
6049        synchronized(this) {
6050            if (mMainStack.mResumedActivity != null
6051                    && mMainStack.mResumedActivity.task.taskId == task) {
6052                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6053                        Binder.getCallingUid(), "Task to back")) {
6054                    return;
6055                }
6056            }
6057            final long origId = Binder.clearCallingIdentity();
6058            mMainStack.moveTaskToBackLocked(task, null);
6059            Binder.restoreCallingIdentity(origId);
6060        }
6061    }
6062
6063    /**
6064     * Moves an activity, and all of the other activities within the same task, to the bottom
6065     * of the history stack.  The activity's order within the task is unchanged.
6066     *
6067     * @param token A reference to the activity we wish to move
6068     * @param nonRoot If false then this only works if the activity is the root
6069     *                of a task; if true it will work for any activity in a task.
6070     * @return Returns true if the move completed, false if not.
6071     */
6072    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6073        enforceNotIsolatedCaller("moveActivityTaskToBack");
6074        synchronized(this) {
6075            final long origId = Binder.clearCallingIdentity();
6076            int taskId = getTaskForActivityLocked(token, !nonRoot);
6077            if (taskId >= 0) {
6078                return mMainStack.moveTaskToBackLocked(taskId, null);
6079            }
6080            Binder.restoreCallingIdentity(origId);
6081        }
6082        return false;
6083    }
6084
6085    public void moveTaskBackwards(int task) {
6086        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6087                "moveTaskBackwards()");
6088
6089        synchronized(this) {
6090            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6091                    Binder.getCallingUid(), "Task backwards")) {
6092                return;
6093            }
6094            final long origId = Binder.clearCallingIdentity();
6095            moveTaskBackwardsLocked(task);
6096            Binder.restoreCallingIdentity(origId);
6097        }
6098    }
6099
6100    private final void moveTaskBackwardsLocked(int task) {
6101        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6102    }
6103
6104    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6105        synchronized(this) {
6106            return getTaskForActivityLocked(token, onlyRoot);
6107        }
6108    }
6109
6110    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6111        final int N = mMainStack.mHistory.size();
6112        TaskRecord lastTask = null;
6113        for (int i=0; i<N; i++) {
6114            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6115            if (r.appToken == token) {
6116                if (!onlyRoot || lastTask != r.task) {
6117                    return r.task.taskId;
6118                }
6119                return -1;
6120            }
6121            lastTask = r.task;
6122        }
6123
6124        return -1;
6125    }
6126
6127    // =========================================================
6128    // THUMBNAILS
6129    // =========================================================
6130
6131    public void reportThumbnail(IBinder token,
6132            Bitmap thumbnail, CharSequence description) {
6133        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6134        final long origId = Binder.clearCallingIdentity();
6135        sendPendingThumbnail(null, token, thumbnail, description, true);
6136        Binder.restoreCallingIdentity(origId);
6137    }
6138
6139    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6140            Bitmap thumbnail, CharSequence description, boolean always) {
6141        TaskRecord task = null;
6142        ArrayList receivers = null;
6143
6144        //System.out.println("Send pending thumbnail: " + r);
6145
6146        synchronized(this) {
6147            if (r == null) {
6148                r = mMainStack.isInStackLocked(token);
6149                if (r == null) {
6150                    return;
6151                }
6152            }
6153            if (thumbnail == null && r.thumbHolder != null) {
6154                thumbnail = r.thumbHolder.lastThumbnail;
6155                description = r.thumbHolder.lastDescription;
6156            }
6157            if (thumbnail == null && !always) {
6158                // If there is no thumbnail, and this entry is not actually
6159                // going away, then abort for now and pick up the next
6160                // thumbnail we get.
6161                return;
6162            }
6163            task = r.task;
6164
6165            int N = mPendingThumbnails.size();
6166            int i=0;
6167            while (i<N) {
6168                PendingThumbnailsRecord pr =
6169                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6170                //System.out.println("Looking in " + pr.pendingRecords);
6171                if (pr.pendingRecords.remove(r)) {
6172                    if (receivers == null) {
6173                        receivers = new ArrayList();
6174                    }
6175                    receivers.add(pr);
6176                    if (pr.pendingRecords.size() == 0) {
6177                        pr.finished = true;
6178                        mPendingThumbnails.remove(i);
6179                        N--;
6180                        continue;
6181                    }
6182                }
6183                i++;
6184            }
6185        }
6186
6187        if (receivers != null) {
6188            final int N = receivers.size();
6189            for (int i=0; i<N; i++) {
6190                try {
6191                    PendingThumbnailsRecord pr =
6192                        (PendingThumbnailsRecord)receivers.get(i);
6193                    pr.receiver.newThumbnail(
6194                        task != null ? task.taskId : -1, thumbnail, description);
6195                    if (pr.finished) {
6196                        pr.receiver.finished();
6197                    }
6198                } catch (Exception e) {
6199                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6200                }
6201            }
6202        }
6203    }
6204
6205    // =========================================================
6206    // CONTENT PROVIDERS
6207    // =========================================================
6208
6209    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6210        List<ProviderInfo> providers = null;
6211        try {
6212            providers = AppGlobals.getPackageManager().
6213                queryContentProviders(app.processName, app.uid,
6214                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6215        } catch (RemoteException ex) {
6216        }
6217        if (DEBUG_MU)
6218            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6219        int userId = app.userId;
6220        if (providers != null) {
6221            int N = providers.size();
6222            for (int i=0; i<N; i++) {
6223                ProviderInfo cpi =
6224                    (ProviderInfo)providers.get(i);
6225                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6226                        cpi.name, cpi.flags);
6227                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6228                    // This is a singleton provider, but a user besides the
6229                    // default user is asking to initialize a process it runs
6230                    // in...  well, no, it doesn't actually run in this process,
6231                    // it runs in the process of the default user.  Get rid of it.
6232                    providers.remove(i);
6233                    N--;
6234                    continue;
6235                }
6236
6237                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6238                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6239                if (cpr == null) {
6240                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6241                    mProviderMap.putProviderByClass(comp, cpr);
6242                }
6243                if (DEBUG_MU)
6244                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6245                app.pubProviders.put(cpi.name, cpr);
6246                app.addPackage(cpi.applicationInfo.packageName);
6247                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6248            }
6249        }
6250        return providers;
6251    }
6252
6253    /**
6254     * Check if {@link ProcessRecord} has a possible chance at accessing the
6255     * given {@link ProviderInfo}. Final permission checking is always done
6256     * in {@link ContentProvider}.
6257     */
6258    private final String checkContentProviderPermissionLocked(
6259            ProviderInfo cpi, ProcessRecord r) {
6260        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6261        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6262        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6263                cpi.applicationInfo.uid, cpi.exported)
6264                == PackageManager.PERMISSION_GRANTED) {
6265            return null;
6266        }
6267        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6268                cpi.applicationInfo.uid, cpi.exported)
6269                == PackageManager.PERMISSION_GRANTED) {
6270            return null;
6271        }
6272
6273        PathPermission[] pps = cpi.pathPermissions;
6274        if (pps != null) {
6275            int i = pps.length;
6276            while (i > 0) {
6277                i--;
6278                PathPermission pp = pps[i];
6279                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6280                        cpi.applicationInfo.uid, cpi.exported)
6281                        == PackageManager.PERMISSION_GRANTED) {
6282                    return null;
6283                }
6284                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6285                        cpi.applicationInfo.uid, cpi.exported)
6286                        == PackageManager.PERMISSION_GRANTED) {
6287                    return null;
6288                }
6289            }
6290        }
6291
6292        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6293        if (perms != null) {
6294            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6295                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6296                    return null;
6297                }
6298            }
6299        }
6300
6301        String msg;
6302        if (!cpi.exported) {
6303            msg = "Permission Denial: opening provider " + cpi.name
6304                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6305                    + ", uid=" + callingUid + ") that is not exported from uid "
6306                    + cpi.applicationInfo.uid;
6307        } else {
6308            msg = "Permission Denial: opening provider " + cpi.name
6309                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6310                    + ", uid=" + callingUid + ") requires "
6311                    + cpi.readPermission + " or " + cpi.writePermission;
6312        }
6313        Slog.w(TAG, msg);
6314        return msg;
6315    }
6316
6317    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6318            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6319        if (r != null) {
6320            for (int i=0; i<r.conProviders.size(); i++) {
6321                ContentProviderConnection conn = r.conProviders.get(i);
6322                if (conn.provider == cpr) {
6323                    if (DEBUG_PROVIDER) Slog.v(TAG,
6324                            "Adding provider requested by "
6325                            + r.processName + " from process "
6326                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6327                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6328                    if (stable) {
6329                        conn.stableCount++;
6330                        conn.numStableIncs++;
6331                    } else {
6332                        conn.unstableCount++;
6333                        conn.numUnstableIncs++;
6334                    }
6335                    return conn;
6336                }
6337            }
6338            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6339            if (stable) {
6340                conn.stableCount = 1;
6341                conn.numStableIncs = 1;
6342            } else {
6343                conn.unstableCount = 1;
6344                conn.numUnstableIncs = 1;
6345            }
6346            cpr.connections.add(conn);
6347            r.conProviders.add(conn);
6348            return conn;
6349        }
6350        cpr.addExternalProcessHandleLocked(externalProcessToken);
6351        return null;
6352    }
6353
6354    boolean decProviderCountLocked(ContentProviderConnection conn,
6355            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6356        if (conn != null) {
6357            cpr = conn.provider;
6358            if (DEBUG_PROVIDER) Slog.v(TAG,
6359                    "Removing provider requested by "
6360                    + conn.client.processName + " from process "
6361                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6362                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6363            if (stable) {
6364                conn.stableCount--;
6365            } else {
6366                conn.unstableCount--;
6367            }
6368            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6369                cpr.connections.remove(conn);
6370                conn.client.conProviders.remove(conn);
6371                return true;
6372            }
6373            return false;
6374        }
6375        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6376        return false;
6377    }
6378
6379    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6380            String name, IBinder token, boolean stable, int userId) {
6381        ContentProviderRecord cpr;
6382        ContentProviderConnection conn = null;
6383        ProviderInfo cpi = null;
6384
6385        synchronized(this) {
6386            ProcessRecord r = null;
6387            if (caller != null) {
6388                r = getRecordForAppLocked(caller);
6389                if (r == null) {
6390                    throw new SecurityException(
6391                            "Unable to find app for caller " + caller
6392                          + " (pid=" + Binder.getCallingPid()
6393                          + ") when getting content provider " + name);
6394                }
6395                if (r.userId != userId) {
6396                    throw new SecurityException("Calling requested user " + userId
6397                            + " but app is user " + r.userId);
6398                }
6399            }
6400
6401            // First check if this content provider has been published...
6402            cpr = mProviderMap.getProviderByName(name, userId);
6403            boolean providerRunning = cpr != null;
6404            if (providerRunning) {
6405                cpi = cpr.info;
6406                String msg;
6407                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6408                    throw new SecurityException(msg);
6409                }
6410
6411                if (r != null && cpr.canRunHere(r)) {
6412                    // This provider has been published or is in the process
6413                    // of being published...  but it is also allowed to run
6414                    // in the caller's process, so don't make a connection
6415                    // and just let the caller instantiate its own instance.
6416                    ContentProviderHolder holder = cpr.newHolder(null);
6417                    // don't give caller the provider object, it needs
6418                    // to make its own.
6419                    holder.provider = null;
6420                    return holder;
6421                }
6422
6423                final long origId = Binder.clearCallingIdentity();
6424
6425                // In this case the provider instance already exists, so we can
6426                // return it right away.
6427                conn = incProviderCountLocked(r, cpr, token, stable);
6428                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6429                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6430                        // If this is a perceptible app accessing the provider,
6431                        // make sure to count it as being accessed and thus
6432                        // back up on the LRU list.  This is good because
6433                        // content providers are often expensive to start.
6434                        updateLruProcessLocked(cpr.proc, false, true);
6435                    }
6436                }
6437
6438                if (cpr.proc != null) {
6439                    if (false) {
6440                        if (cpr.name.flattenToShortString().equals(
6441                                "com.android.providers.calendar/.CalendarProvider2")) {
6442                            Slog.v(TAG, "****************** KILLING "
6443                                + cpr.name.flattenToShortString());
6444                            Process.killProcess(cpr.proc.pid);
6445                        }
6446                    }
6447                    boolean success = updateOomAdjLocked(cpr.proc);
6448                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6449                    // NOTE: there is still a race here where a signal could be
6450                    // pending on the process even though we managed to update its
6451                    // adj level.  Not sure what to do about this, but at least
6452                    // the race is now smaller.
6453                    if (!success) {
6454                        // Uh oh...  it looks like the provider's process
6455                        // has been killed on us.  We need to wait for a new
6456                        // process to be started, and make sure its death
6457                        // doesn't kill our process.
6458                        Slog.i(TAG,
6459                                "Existing provider " + cpr.name.flattenToShortString()
6460                                + " is crashing; detaching " + r);
6461                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6462                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6463                        if (!lastRef) {
6464                            // This wasn't the last ref our process had on
6465                            // the provider...  we have now been killed, bail.
6466                            return null;
6467                        }
6468                        providerRunning = false;
6469                        conn = null;
6470                    }
6471                }
6472
6473                Binder.restoreCallingIdentity(origId);
6474            }
6475
6476            boolean singleton;
6477            if (!providerRunning) {
6478                try {
6479                    cpi = AppGlobals.getPackageManager().
6480                        resolveContentProvider(name,
6481                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6482                } catch (RemoteException ex) {
6483                }
6484                if (cpi == null) {
6485                    return null;
6486                }
6487                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6488                        cpi.name, cpi.flags);
6489                if (singleton) {
6490                    userId = 0;
6491                }
6492                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6493
6494                String msg;
6495                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6496                    throw new SecurityException(msg);
6497                }
6498
6499                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6500                        && !cpi.processName.equals("system")) {
6501                    // If this content provider does not run in the system
6502                    // process, and the system is not yet ready to run other
6503                    // processes, then fail fast instead of hanging.
6504                    throw new IllegalArgumentException(
6505                            "Attempt to launch content provider before system ready");
6506                }
6507
6508                // Make sure that the user who owns this provider is started.  If not,
6509                // we don't want to allow it to run.
6510                if (mStartedUsers.get(userId) == null) {
6511                    Slog.w(TAG, "Unable to launch app "
6512                            + cpi.applicationInfo.packageName + "/"
6513                            + cpi.applicationInfo.uid + " for provider "
6514                            + name + ": user " + userId + " is stopped");
6515                    return null;
6516                }
6517
6518                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6519                cpr = mProviderMap.getProviderByClass(comp, userId);
6520                final boolean firstClass = cpr == null;
6521                if (firstClass) {
6522                    try {
6523                        ApplicationInfo ai =
6524                            AppGlobals.getPackageManager().
6525                                getApplicationInfo(
6526                                        cpi.applicationInfo.packageName,
6527                                        STOCK_PM_FLAGS, userId);
6528                        if (ai == null) {
6529                            Slog.w(TAG, "No package info for content provider "
6530                                    + cpi.name);
6531                            return null;
6532                        }
6533                        ai = getAppInfoForUser(ai, userId);
6534                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6535                    } catch (RemoteException ex) {
6536                        // pm is in same process, this will never happen.
6537                    }
6538                }
6539
6540                if (r != null && cpr.canRunHere(r)) {
6541                    // If this is a multiprocess provider, then just return its
6542                    // info and allow the caller to instantiate it.  Only do
6543                    // this if the provider is the same user as the caller's
6544                    // process, or can run as root (so can be in any process).
6545                    return cpr.newHolder(null);
6546                }
6547
6548                if (DEBUG_PROVIDER) {
6549                    RuntimeException e = new RuntimeException("here");
6550                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6551                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6552                }
6553
6554                // This is single process, and our app is now connecting to it.
6555                // See if we are already in the process of launching this
6556                // provider.
6557                final int N = mLaunchingProviders.size();
6558                int i;
6559                for (i=0; i<N; i++) {
6560                    if (mLaunchingProviders.get(i) == cpr) {
6561                        break;
6562                    }
6563                }
6564
6565                // If the provider is not already being launched, then get it
6566                // started.
6567                if (i >= N) {
6568                    final long origId = Binder.clearCallingIdentity();
6569
6570                    try {
6571                        // Content provider is now in use, its package can't be stopped.
6572                        try {
6573                            AppGlobals.getPackageManager().setPackageStoppedState(
6574                                    cpr.appInfo.packageName, false, userId);
6575                        } catch (RemoteException e) {
6576                        } catch (IllegalArgumentException e) {
6577                            Slog.w(TAG, "Failed trying to unstop package "
6578                                    + cpr.appInfo.packageName + ": " + e);
6579                        }
6580
6581                        ProcessRecord proc = startProcessLocked(cpi.processName,
6582                                cpr.appInfo, false, 0, "content provider",
6583                                new ComponentName(cpi.applicationInfo.packageName,
6584                                        cpi.name), false, false);
6585                        if (proc == null) {
6586                            Slog.w(TAG, "Unable to launch app "
6587                                    + cpi.applicationInfo.packageName + "/"
6588                                    + cpi.applicationInfo.uid + " for provider "
6589                                    + name + ": process is bad");
6590                            return null;
6591                        }
6592                        cpr.launchingApp = proc;
6593                        mLaunchingProviders.add(cpr);
6594                    } finally {
6595                        Binder.restoreCallingIdentity(origId);
6596                    }
6597                }
6598
6599                // Make sure the provider is published (the same provider class
6600                // may be published under multiple names).
6601                if (firstClass) {
6602                    mProviderMap.putProviderByClass(comp, cpr);
6603                }
6604
6605                mProviderMap.putProviderByName(name, cpr);
6606                conn = incProviderCountLocked(r, cpr, token, stable);
6607                if (conn != null) {
6608                    conn.waiting = true;
6609                }
6610            }
6611        }
6612
6613        // Wait for the provider to be published...
6614        synchronized (cpr) {
6615            while (cpr.provider == null) {
6616                if (cpr.launchingApp == null) {
6617                    Slog.w(TAG, "Unable to launch app "
6618                            + cpi.applicationInfo.packageName + "/"
6619                            + cpi.applicationInfo.uid + " for provider "
6620                            + name + ": launching app became null");
6621                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6622                            cpi.applicationInfo.packageName,
6623                            cpi.applicationInfo.uid, name);
6624                    return null;
6625                }
6626                try {
6627                    if (DEBUG_MU) {
6628                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6629                                + cpr.launchingApp);
6630                    }
6631                    if (conn != null) {
6632                        conn.waiting = true;
6633                    }
6634                    cpr.wait();
6635                } catch (InterruptedException ex) {
6636                } finally {
6637                    if (conn != null) {
6638                        conn.waiting = false;
6639                    }
6640                }
6641            }
6642        }
6643        return cpr != null ? cpr.newHolder(conn) : null;
6644    }
6645
6646    public final ContentProviderHolder getContentProvider(
6647            IApplicationThread caller, String name, boolean stable) {
6648        enforceNotIsolatedCaller("getContentProvider");
6649        if (caller == null) {
6650            String msg = "null IApplicationThread when getting content provider "
6651                    + name;
6652            Slog.w(TAG, msg);
6653            throw new SecurityException(msg);
6654        }
6655
6656        return getContentProviderImpl(caller, name, null, stable,
6657                UserHandle.getCallingUserId());
6658    }
6659
6660    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6661        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6662            "Do not have permission in call getContentProviderExternal()");
6663        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6664    }
6665
6666    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6667            IBinder token, int userId) {
6668        return getContentProviderImpl(null, name, token, true, userId);
6669    }
6670
6671    /**
6672     * Drop a content provider from a ProcessRecord's bookkeeping
6673     * @param cpr
6674     */
6675    public void removeContentProvider(IBinder connection, boolean stable) {
6676        enforceNotIsolatedCaller("removeContentProvider");
6677        synchronized (this) {
6678            ContentProviderConnection conn;
6679            try {
6680                conn = (ContentProviderConnection)connection;
6681            } catch (ClassCastException e) {
6682                String msg ="removeContentProvider: " + connection
6683                        + " not a ContentProviderConnection";
6684                Slog.w(TAG, msg);
6685                throw new IllegalArgumentException(msg);
6686            }
6687            if (conn == null) {
6688                throw new NullPointerException("connection is null");
6689            }
6690            if (decProviderCountLocked(conn, null, null, stable)) {
6691                updateOomAdjLocked();
6692            }
6693        }
6694    }
6695
6696    public void removeContentProviderExternal(String name, IBinder token) {
6697        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6698            "Do not have permission in call removeContentProviderExternal()");
6699        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6700    }
6701
6702    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6703        synchronized (this) {
6704            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6705            if(cpr == null) {
6706                //remove from mProvidersByClass
6707                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6708                return;
6709            }
6710
6711            //update content provider record entry info
6712            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6713            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6714            if (localCpr.hasExternalProcessHandles()) {
6715                if (localCpr.removeExternalProcessHandleLocked(token)) {
6716                    updateOomAdjLocked();
6717                } else {
6718                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6719                            + " with no external reference for token: "
6720                            + token + ".");
6721                }
6722            } else {
6723                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6724                        + " with no external references.");
6725            }
6726        }
6727    }
6728
6729    public final void publishContentProviders(IApplicationThread caller,
6730            List<ContentProviderHolder> providers) {
6731        if (providers == null) {
6732            return;
6733        }
6734
6735        enforceNotIsolatedCaller("publishContentProviders");
6736        synchronized (this) {
6737            final ProcessRecord r = getRecordForAppLocked(caller);
6738            if (DEBUG_MU)
6739                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6740            if (r == null) {
6741                throw new SecurityException(
6742                        "Unable to find app for caller " + caller
6743                      + " (pid=" + Binder.getCallingPid()
6744                      + ") when publishing content providers");
6745            }
6746
6747            final long origId = Binder.clearCallingIdentity();
6748
6749            final int N = providers.size();
6750            for (int i=0; i<N; i++) {
6751                ContentProviderHolder src = providers.get(i);
6752                if (src == null || src.info == null || src.provider == null) {
6753                    continue;
6754                }
6755                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6756                if (DEBUG_MU)
6757                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6758                if (dst != null) {
6759                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6760                    mProviderMap.putProviderByClass(comp, dst);
6761                    String names[] = dst.info.authority.split(";");
6762                    for (int j = 0; j < names.length; j++) {
6763                        mProviderMap.putProviderByName(names[j], dst);
6764                    }
6765
6766                    int NL = mLaunchingProviders.size();
6767                    int j;
6768                    for (j=0; j<NL; j++) {
6769                        if (mLaunchingProviders.get(j) == dst) {
6770                            mLaunchingProviders.remove(j);
6771                            j--;
6772                            NL--;
6773                        }
6774                    }
6775                    synchronized (dst) {
6776                        dst.provider = src.provider;
6777                        dst.proc = r;
6778                        dst.notifyAll();
6779                    }
6780                    updateOomAdjLocked(r);
6781                }
6782            }
6783
6784            Binder.restoreCallingIdentity(origId);
6785        }
6786    }
6787
6788    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6789        ContentProviderConnection conn;
6790        try {
6791            conn = (ContentProviderConnection)connection;
6792        } catch (ClassCastException e) {
6793            String msg ="refContentProvider: " + connection
6794                    + " not a ContentProviderConnection";
6795            Slog.w(TAG, msg);
6796            throw new IllegalArgumentException(msg);
6797        }
6798        if (conn == null) {
6799            throw new NullPointerException("connection is null");
6800        }
6801
6802        synchronized (this) {
6803            if (stable > 0) {
6804                conn.numStableIncs += stable;
6805            }
6806            stable = conn.stableCount + stable;
6807            if (stable < 0) {
6808                throw new IllegalStateException("stableCount < 0: " + stable);
6809            }
6810
6811            if (unstable > 0) {
6812                conn.numUnstableIncs += unstable;
6813            }
6814            unstable = conn.unstableCount + unstable;
6815            if (unstable < 0) {
6816                throw new IllegalStateException("unstableCount < 0: " + unstable);
6817            }
6818
6819            if ((stable+unstable) <= 0) {
6820                throw new IllegalStateException("ref counts can't go to zero here: stable="
6821                        + stable + " unstable=" + unstable);
6822            }
6823            conn.stableCount = stable;
6824            conn.unstableCount = unstable;
6825            return !conn.dead;
6826        }
6827    }
6828
6829    public void unstableProviderDied(IBinder connection) {
6830        ContentProviderConnection conn;
6831        try {
6832            conn = (ContentProviderConnection)connection;
6833        } catch (ClassCastException e) {
6834            String msg ="refContentProvider: " + connection
6835                    + " not a ContentProviderConnection";
6836            Slog.w(TAG, msg);
6837            throw new IllegalArgumentException(msg);
6838        }
6839        if (conn == null) {
6840            throw new NullPointerException("connection is null");
6841        }
6842
6843        // Safely retrieve the content provider associated with the connection.
6844        IContentProvider provider;
6845        synchronized (this) {
6846            provider = conn.provider.provider;
6847        }
6848
6849        if (provider == null) {
6850            // Um, yeah, we're way ahead of you.
6851            return;
6852        }
6853
6854        // Make sure the caller is being honest with us.
6855        if (provider.asBinder().pingBinder()) {
6856            // Er, no, still looks good to us.
6857            synchronized (this) {
6858                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6859                        + " says " + conn + " died, but we don't agree");
6860                return;
6861            }
6862        }
6863
6864        // Well look at that!  It's dead!
6865        synchronized (this) {
6866            if (conn.provider.provider != provider) {
6867                // But something changed...  good enough.
6868                return;
6869            }
6870
6871            ProcessRecord proc = conn.provider.proc;
6872            if (proc == null || proc.thread == null) {
6873                // Seems like the process is already cleaned up.
6874                return;
6875            }
6876
6877            // As far as we're concerned, this is just like receiving a
6878            // death notification...  just a bit prematurely.
6879            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6880                    + ") early provider death");
6881            final long ident = Binder.clearCallingIdentity();
6882            try {
6883                appDiedLocked(proc, proc.pid, proc.thread);
6884            } finally {
6885                Binder.restoreCallingIdentity(ident);
6886            }
6887        }
6888    }
6889
6890    public static final void installSystemProviders() {
6891        List<ProviderInfo> providers;
6892        synchronized (mSelf) {
6893            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6894            providers = mSelf.generateApplicationProvidersLocked(app);
6895            if (providers != null) {
6896                for (int i=providers.size()-1; i>=0; i--) {
6897                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6898                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6899                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6900                                + ": not system .apk");
6901                        providers.remove(i);
6902                    }
6903                }
6904            }
6905        }
6906        if (providers != null) {
6907            mSystemThread.installSystemProviders(providers);
6908        }
6909
6910        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6911
6912        mSelf.mUsageStatsService.monitorPackages();
6913    }
6914
6915    /**
6916     * Allows app to retrieve the MIME type of a URI without having permission
6917     * to access its content provider.
6918     *
6919     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6920     *
6921     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6922     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6923     */
6924    public String getProviderMimeType(Uri uri, int userId) {
6925        enforceNotIsolatedCaller("getProviderMimeType");
6926        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6927                userId, false, true, "getProviderMimeType", null);
6928        final String name = uri.getAuthority();
6929        final long ident = Binder.clearCallingIdentity();
6930        ContentProviderHolder holder = null;
6931
6932        try {
6933            holder = getContentProviderExternalUnchecked(name, null, userId);
6934            if (holder != null) {
6935                return holder.provider.getType(uri);
6936            }
6937        } catch (RemoteException e) {
6938            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6939            return null;
6940        } finally {
6941            if (holder != null) {
6942                removeContentProviderExternalUnchecked(name, null, userId);
6943            }
6944            Binder.restoreCallingIdentity(ident);
6945        }
6946
6947        return null;
6948    }
6949
6950    // =========================================================
6951    // GLOBAL MANAGEMENT
6952    // =========================================================
6953
6954    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6955            ApplicationInfo info, String customProcess, boolean isolated) {
6956        String proc = customProcess != null ? customProcess : info.processName;
6957        BatteryStatsImpl.Uid.Proc ps = null;
6958        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6959        int uid = info.uid;
6960        if (isolated) {
6961            int userId = UserHandle.getUserId(uid);
6962            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6963            uid = 0;
6964            while (true) {
6965                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6966                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6967                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6968                }
6969                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6970                mNextIsolatedProcessUid++;
6971                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6972                    // No process for this uid, use it.
6973                    break;
6974                }
6975                stepsLeft--;
6976                if (stepsLeft <= 0) {
6977                    return null;
6978                }
6979            }
6980        }
6981        synchronized (stats) {
6982            ps = stats.getProcessStatsLocked(info.uid, proc);
6983        }
6984        return new ProcessRecord(ps, thread, info, proc, uid);
6985    }
6986
6987    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6988        ProcessRecord app;
6989        if (!isolated) {
6990            app = getProcessRecordLocked(info.processName, info.uid);
6991        } else {
6992            app = null;
6993        }
6994
6995        if (app == null) {
6996            app = newProcessRecordLocked(null, info, null, isolated);
6997            mProcessNames.put(info.processName, app.uid, app);
6998            if (isolated) {
6999                mIsolatedProcesses.put(app.uid, app);
7000            }
7001            updateLruProcessLocked(app, true, true);
7002        }
7003
7004        // This package really, really can not be stopped.
7005        try {
7006            AppGlobals.getPackageManager().setPackageStoppedState(
7007                    info.packageName, false, UserHandle.getUserId(app.uid));
7008        } catch (RemoteException e) {
7009        } catch (IllegalArgumentException e) {
7010            Slog.w(TAG, "Failed trying to unstop package "
7011                    + info.packageName + ": " + e);
7012        }
7013
7014        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7015                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7016            app.persistent = true;
7017            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7018        }
7019        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7020            mPersistentStartingProcesses.add(app);
7021            startProcessLocked(app, "added application", app.processName);
7022        }
7023
7024        return app;
7025    }
7026
7027    public void unhandledBack() {
7028        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7029                "unhandledBack()");
7030
7031        synchronized(this) {
7032            int count = mMainStack.mHistory.size();
7033            if (DEBUG_SWITCH) Slog.d(
7034                TAG, "Performing unhandledBack(): stack size = " + count);
7035            if (count > 1) {
7036                final long origId = Binder.clearCallingIdentity();
7037                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7038                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7039                Binder.restoreCallingIdentity(origId);
7040            }
7041        }
7042    }
7043
7044    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7045        enforceNotIsolatedCaller("openContentUri");
7046        final int userId = UserHandle.getCallingUserId();
7047        String name = uri.getAuthority();
7048        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7049        ParcelFileDescriptor pfd = null;
7050        if (cph != null) {
7051            // We record the binder invoker's uid in thread-local storage before
7052            // going to the content provider to open the file.  Later, in the code
7053            // that handles all permissions checks, we look for this uid and use
7054            // that rather than the Activity Manager's own uid.  The effect is that
7055            // we do the check against the caller's permissions even though it looks
7056            // to the content provider like the Activity Manager itself is making
7057            // the request.
7058            sCallerIdentity.set(new Identity(
7059                    Binder.getCallingPid(), Binder.getCallingUid()));
7060            try {
7061                pfd = cph.provider.openFile(uri, "r");
7062            } catch (FileNotFoundException e) {
7063                // do nothing; pfd will be returned null
7064            } finally {
7065                // Ensure that whatever happens, we clean up the identity state
7066                sCallerIdentity.remove();
7067            }
7068
7069            // We've got the fd now, so we're done with the provider.
7070            removeContentProviderExternalUnchecked(name, null, userId);
7071        } else {
7072            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7073        }
7074        return pfd;
7075    }
7076
7077    // Actually is sleeping or shutting down or whatever else in the future
7078    // is an inactive state.
7079    public boolean isSleeping() {
7080        return mSleeping || mShuttingDown;
7081    }
7082
7083    public void goingToSleep() {
7084        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7085                != PackageManager.PERMISSION_GRANTED) {
7086            throw new SecurityException("Requires permission "
7087                    + android.Manifest.permission.DEVICE_POWER);
7088        }
7089
7090        synchronized(this) {
7091            mWentToSleep = true;
7092            updateEventDispatchingLocked();
7093
7094            if (!mSleeping) {
7095                mSleeping = true;
7096                mMainStack.stopIfSleepingLocked();
7097
7098                // Initialize the wake times of all processes.
7099                checkExcessivePowerUsageLocked(false);
7100                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7101                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7102                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7103            }
7104        }
7105    }
7106
7107    public boolean shutdown(int timeout) {
7108        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7109                != PackageManager.PERMISSION_GRANTED) {
7110            throw new SecurityException("Requires permission "
7111                    + android.Manifest.permission.SHUTDOWN);
7112        }
7113
7114        boolean timedout = false;
7115
7116        synchronized(this) {
7117            mShuttingDown = true;
7118            updateEventDispatchingLocked();
7119
7120            if (mMainStack.mResumedActivity != null) {
7121                mMainStack.stopIfSleepingLocked();
7122                final long endTime = System.currentTimeMillis() + timeout;
7123                while (mMainStack.mResumedActivity != null
7124                        || mMainStack.mPausingActivity != null) {
7125                    long delay = endTime - System.currentTimeMillis();
7126                    if (delay <= 0) {
7127                        Slog.w(TAG, "Activity manager shutdown timed out");
7128                        timedout = true;
7129                        break;
7130                    }
7131                    try {
7132                        this.wait();
7133                    } catch (InterruptedException e) {
7134                    }
7135                }
7136            }
7137        }
7138
7139        mUsageStatsService.shutdown();
7140        mBatteryStatsService.shutdown();
7141
7142        return timedout;
7143    }
7144
7145    public final void activitySlept(IBinder token) {
7146        if (localLOGV) Slog.v(
7147            TAG, "Activity slept: token=" + token);
7148
7149        ActivityRecord r = null;
7150
7151        final long origId = Binder.clearCallingIdentity();
7152
7153        synchronized (this) {
7154            r = mMainStack.isInStackLocked(token);
7155            if (r != null) {
7156                mMainStack.activitySleptLocked(r);
7157            }
7158        }
7159
7160        Binder.restoreCallingIdentity(origId);
7161    }
7162
7163    private void comeOutOfSleepIfNeededLocked() {
7164        if (!mWentToSleep && !mLockScreenShown) {
7165            if (mSleeping) {
7166                mSleeping = false;
7167                mMainStack.awakeFromSleepingLocked();
7168                mMainStack.resumeTopActivityLocked(null);
7169            }
7170        }
7171    }
7172
7173    public void wakingUp() {
7174        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7175                != PackageManager.PERMISSION_GRANTED) {
7176            throw new SecurityException("Requires permission "
7177                    + android.Manifest.permission.DEVICE_POWER);
7178        }
7179
7180        synchronized(this) {
7181            mWentToSleep = false;
7182            updateEventDispatchingLocked();
7183            comeOutOfSleepIfNeededLocked();
7184        }
7185    }
7186
7187    private void updateEventDispatchingLocked() {
7188        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7189    }
7190
7191    public void setLockScreenShown(boolean shown) {
7192        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7193                != PackageManager.PERMISSION_GRANTED) {
7194            throw new SecurityException("Requires permission "
7195                    + android.Manifest.permission.DEVICE_POWER);
7196        }
7197
7198        synchronized(this) {
7199            mLockScreenShown = shown;
7200            comeOutOfSleepIfNeededLocked();
7201        }
7202    }
7203
7204    public void stopAppSwitches() {
7205        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7206                != PackageManager.PERMISSION_GRANTED) {
7207            throw new SecurityException("Requires permission "
7208                    + android.Manifest.permission.STOP_APP_SWITCHES);
7209        }
7210
7211        synchronized(this) {
7212            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7213                    + APP_SWITCH_DELAY_TIME;
7214            mDidAppSwitch = false;
7215            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7216            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7217            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7218        }
7219    }
7220
7221    public void resumeAppSwitches() {
7222        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7223                != PackageManager.PERMISSION_GRANTED) {
7224            throw new SecurityException("Requires permission "
7225                    + android.Manifest.permission.STOP_APP_SWITCHES);
7226        }
7227
7228        synchronized(this) {
7229            // Note that we don't execute any pending app switches... we will
7230            // let those wait until either the timeout, or the next start
7231            // activity request.
7232            mAppSwitchesAllowedTime = 0;
7233        }
7234    }
7235
7236    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7237            String name) {
7238        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7239            return true;
7240        }
7241
7242        final int perm = checkComponentPermission(
7243                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7244                callingUid, -1, true);
7245        if (perm == PackageManager.PERMISSION_GRANTED) {
7246            return true;
7247        }
7248
7249        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7250        return false;
7251    }
7252
7253    public void setDebugApp(String packageName, boolean waitForDebugger,
7254            boolean persistent) {
7255        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7256                "setDebugApp()");
7257
7258        // Note that this is not really thread safe if there are multiple
7259        // callers into it at the same time, but that's not a situation we
7260        // care about.
7261        if (persistent) {
7262            final ContentResolver resolver = mContext.getContentResolver();
7263            Settings.System.putString(
7264                resolver, Settings.System.DEBUG_APP,
7265                packageName);
7266            Settings.System.putInt(
7267                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7268                waitForDebugger ? 1 : 0);
7269        }
7270
7271        synchronized (this) {
7272            if (!persistent) {
7273                mOrigDebugApp = mDebugApp;
7274                mOrigWaitForDebugger = mWaitForDebugger;
7275            }
7276            mDebugApp = packageName;
7277            mWaitForDebugger = waitForDebugger;
7278            mDebugTransient = !persistent;
7279            if (packageName != null) {
7280                final long origId = Binder.clearCallingIdentity();
7281                forceStopPackageLocked(packageName, -1, false, false, true, true,
7282                        UserHandle.USER_ALL);
7283                Binder.restoreCallingIdentity(origId);
7284            }
7285        }
7286    }
7287
7288    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7289        synchronized (this) {
7290            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7291            if (!isDebuggable) {
7292                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7293                    throw new SecurityException("Process not debuggable: " + app.packageName);
7294                }
7295            }
7296
7297            mOpenGlTraceApp = processName;
7298        }
7299    }
7300
7301    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7302            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7303        synchronized (this) {
7304            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7305            if (!isDebuggable) {
7306                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7307                    throw new SecurityException("Process not debuggable: " + app.packageName);
7308                }
7309            }
7310            mProfileApp = processName;
7311            mProfileFile = profileFile;
7312            if (mProfileFd != null) {
7313                try {
7314                    mProfileFd.close();
7315                } catch (IOException e) {
7316                }
7317                mProfileFd = null;
7318            }
7319            mProfileFd = profileFd;
7320            mProfileType = 0;
7321            mAutoStopProfiler = autoStopProfiler;
7322        }
7323    }
7324
7325    public void setAlwaysFinish(boolean enabled) {
7326        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7327                "setAlwaysFinish()");
7328
7329        Settings.System.putInt(
7330                mContext.getContentResolver(),
7331                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7332
7333        synchronized (this) {
7334            mAlwaysFinishActivities = enabled;
7335        }
7336    }
7337
7338    public void setActivityController(IActivityController controller) {
7339        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7340                "setActivityController()");
7341        synchronized (this) {
7342            mController = controller;
7343        }
7344    }
7345
7346    public boolean isUserAMonkey() {
7347        // For now the fact that there is a controller implies
7348        // we have a monkey.
7349        synchronized (this) {
7350            return mController != null;
7351        }
7352    }
7353
7354    public void registerProcessObserver(IProcessObserver observer) {
7355        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7356                "registerProcessObserver()");
7357        synchronized (this) {
7358            mProcessObservers.register(observer);
7359        }
7360    }
7361
7362    public void unregisterProcessObserver(IProcessObserver observer) {
7363        synchronized (this) {
7364            mProcessObservers.unregister(observer);
7365        }
7366    }
7367
7368    public void setImmersive(IBinder token, boolean immersive) {
7369        synchronized(this) {
7370            ActivityRecord r = mMainStack.isInStackLocked(token);
7371            if (r == null) {
7372                throw new IllegalArgumentException();
7373            }
7374            r.immersive = immersive;
7375        }
7376    }
7377
7378    public boolean isImmersive(IBinder token) {
7379        synchronized (this) {
7380            ActivityRecord r = mMainStack.isInStackLocked(token);
7381            if (r == null) {
7382                throw new IllegalArgumentException();
7383            }
7384            return r.immersive;
7385        }
7386    }
7387
7388    public boolean isTopActivityImmersive() {
7389        enforceNotIsolatedCaller("startActivity");
7390        synchronized (this) {
7391            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7392            return (r != null) ? r.immersive : false;
7393        }
7394    }
7395
7396    public final void enterSafeMode() {
7397        synchronized(this) {
7398            // It only makes sense to do this before the system is ready
7399            // and started launching other packages.
7400            if (!mSystemReady) {
7401                try {
7402                    AppGlobals.getPackageManager().enterSafeMode();
7403                } catch (RemoteException e) {
7404                }
7405            }
7406        }
7407    }
7408
7409    public final void showSafeModeOverlay() {
7410        View v = LayoutInflater.from(mContext).inflate(
7411                com.android.internal.R.layout.safe_mode, null);
7412        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7413        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7414        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7415        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7416        lp.gravity = Gravity.BOTTOM | Gravity.START;
7417        lp.format = v.getBackground().getOpacity();
7418        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7419                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7420        ((WindowManager)mContext.getSystemService(
7421                Context.WINDOW_SERVICE)).addView(v, lp);
7422    }
7423
7424    public void noteWakeupAlarm(IIntentSender sender) {
7425        if (!(sender instanceof PendingIntentRecord)) {
7426            return;
7427        }
7428        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7429        synchronized (stats) {
7430            if (mBatteryStatsService.isOnBattery()) {
7431                mBatteryStatsService.enforceCallingPermission();
7432                PendingIntentRecord rec = (PendingIntentRecord)sender;
7433                int MY_UID = Binder.getCallingUid();
7434                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7435                BatteryStatsImpl.Uid.Pkg pkg =
7436                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7437                pkg.incWakeupsLocked();
7438            }
7439        }
7440    }
7441
7442    public boolean killPids(int[] pids, String pReason, boolean secure) {
7443        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7444            throw new SecurityException("killPids only available to the system");
7445        }
7446        String reason = (pReason == null) ? "Unknown" : pReason;
7447        // XXX Note: don't acquire main activity lock here, because the window
7448        // manager calls in with its locks held.
7449
7450        boolean killed = false;
7451        synchronized (mPidsSelfLocked) {
7452            int[] types = new int[pids.length];
7453            int worstType = 0;
7454            for (int i=0; i<pids.length; i++) {
7455                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7456                if (proc != null) {
7457                    int type = proc.setAdj;
7458                    types[i] = type;
7459                    if (type > worstType) {
7460                        worstType = type;
7461                    }
7462                }
7463            }
7464
7465            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7466            // then constrain it so we will kill all hidden procs.
7467            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7468                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7469                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7470            }
7471
7472            // If this is not a secure call, don't let it kill processes that
7473            // are important.
7474            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7475                worstType = ProcessList.SERVICE_ADJ;
7476            }
7477
7478            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7479            for (int i=0; i<pids.length; i++) {
7480                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7481                if (proc == null) {
7482                    continue;
7483                }
7484                int adj = proc.setAdj;
7485                if (adj >= worstType && !proc.killedBackground) {
7486                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7487                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7488                            proc.processName, adj, reason);
7489                    killed = true;
7490                    proc.killedBackground = true;
7491                    Process.killProcessQuiet(pids[i]);
7492                }
7493            }
7494        }
7495        return killed;
7496    }
7497
7498    @Override
7499    public boolean killProcessesBelowForeground(String reason) {
7500        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7501            throw new SecurityException("killProcessesBelowForeground() only available to system");
7502        }
7503
7504        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7505    }
7506
7507    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7508        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7509            throw new SecurityException("killProcessesBelowAdj() only available to system");
7510        }
7511
7512        boolean killed = false;
7513        synchronized (mPidsSelfLocked) {
7514            final int size = mPidsSelfLocked.size();
7515            for (int i = 0; i < size; i++) {
7516                final int pid = mPidsSelfLocked.keyAt(i);
7517                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7518                if (proc == null) continue;
7519
7520                final int adj = proc.setAdj;
7521                if (adj > belowAdj && !proc.killedBackground) {
7522                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7523                    EventLog.writeEvent(
7524                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7525                    killed = true;
7526                    proc.killedBackground = true;
7527                    Process.killProcessQuiet(pid);
7528                }
7529            }
7530        }
7531        return killed;
7532    }
7533
7534    public final void startRunning(String pkg, String cls, String action,
7535            String data) {
7536        synchronized(this) {
7537            if (mStartRunning) {
7538                return;
7539            }
7540            mStartRunning = true;
7541            mTopComponent = pkg != null && cls != null
7542                    ? new ComponentName(pkg, cls) : null;
7543            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7544            mTopData = data;
7545            if (!mSystemReady) {
7546                return;
7547            }
7548        }
7549
7550        systemReady(null);
7551    }
7552
7553    private void retrieveSettings() {
7554        final ContentResolver resolver = mContext.getContentResolver();
7555        String debugApp = Settings.System.getString(
7556            resolver, Settings.System.DEBUG_APP);
7557        boolean waitForDebugger = Settings.System.getInt(
7558            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7559        boolean alwaysFinishActivities = Settings.System.getInt(
7560            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7561
7562        Configuration configuration = new Configuration();
7563        Settings.System.getConfiguration(resolver, configuration);
7564
7565        synchronized (this) {
7566            mDebugApp = mOrigDebugApp = debugApp;
7567            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7568            mAlwaysFinishActivities = alwaysFinishActivities;
7569            // This happens before any activities are started, so we can
7570            // change mConfiguration in-place.
7571            updateConfigurationLocked(configuration, null, false, true);
7572            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7573        }
7574    }
7575
7576    public boolean testIsSystemReady() {
7577        // no need to synchronize(this) just to read & return the value
7578        return mSystemReady;
7579    }
7580
7581    private static File getCalledPreBootReceiversFile() {
7582        File dataDir = Environment.getDataDirectory();
7583        File systemDir = new File(dataDir, "system");
7584        File fname = new File(systemDir, "called_pre_boots.dat");
7585        return fname;
7586    }
7587
7588    static final int LAST_DONE_VERSION = 10000;
7589
7590    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7591        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7592        File file = getCalledPreBootReceiversFile();
7593        FileInputStream fis = null;
7594        try {
7595            fis = new FileInputStream(file);
7596            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7597            int fvers = dis.readInt();
7598            if (fvers == LAST_DONE_VERSION) {
7599                String vers = dis.readUTF();
7600                String codename = dis.readUTF();
7601                String build = dis.readUTF();
7602                if (android.os.Build.VERSION.RELEASE.equals(vers)
7603                        && android.os.Build.VERSION.CODENAME.equals(codename)
7604                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7605                    int num = dis.readInt();
7606                    while (num > 0) {
7607                        num--;
7608                        String pkg = dis.readUTF();
7609                        String cls = dis.readUTF();
7610                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7611                    }
7612                }
7613            }
7614        } catch (FileNotFoundException e) {
7615        } catch (IOException e) {
7616            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7617        } finally {
7618            if (fis != null) {
7619                try {
7620                    fis.close();
7621                } catch (IOException e) {
7622                }
7623            }
7624        }
7625        return lastDoneReceivers;
7626    }
7627
7628    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7629        File file = getCalledPreBootReceiversFile();
7630        FileOutputStream fos = null;
7631        DataOutputStream dos = null;
7632        try {
7633            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7634            fos = new FileOutputStream(file);
7635            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7636            dos.writeInt(LAST_DONE_VERSION);
7637            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7638            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7639            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7640            dos.writeInt(list.size());
7641            for (int i=0; i<list.size(); i++) {
7642                dos.writeUTF(list.get(i).getPackageName());
7643                dos.writeUTF(list.get(i).getClassName());
7644            }
7645        } catch (IOException e) {
7646            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7647            file.delete();
7648        } finally {
7649            FileUtils.sync(fos);
7650            if (dos != null) {
7651                try {
7652                    dos.close();
7653                } catch (IOException e) {
7654                    // TODO Auto-generated catch block
7655                    e.printStackTrace();
7656                }
7657            }
7658        }
7659    }
7660
7661    public void systemReady(final Runnable goingCallback) {
7662        synchronized(this) {
7663            if (mSystemReady) {
7664                if (goingCallback != null) goingCallback.run();
7665                return;
7666            }
7667
7668            // Check to see if there are any update receivers to run.
7669            if (!mDidUpdate) {
7670                if (mWaitingUpdate) {
7671                    return;
7672                }
7673                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7674                List<ResolveInfo> ris = null;
7675                try {
7676                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7677                            intent, null, 0, 0);
7678                } catch (RemoteException e) {
7679                }
7680                if (ris != null) {
7681                    for (int i=ris.size()-1; i>=0; i--) {
7682                        if ((ris.get(i).activityInfo.applicationInfo.flags
7683                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7684                            ris.remove(i);
7685                        }
7686                    }
7687                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7688
7689                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7690
7691                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7692                    for (int i=0; i<ris.size(); i++) {
7693                        ActivityInfo ai = ris.get(i).activityInfo;
7694                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7695                        if (lastDoneReceivers.contains(comp)) {
7696                            ris.remove(i);
7697                            i--;
7698                        }
7699                    }
7700
7701                    final int[] users = getUsersLocked();
7702                    for (int i=0; i<ris.size(); i++) {
7703                        ActivityInfo ai = ris.get(i).activityInfo;
7704                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7705                        doneReceivers.add(comp);
7706                        intent.setComponent(comp);
7707                        for (int j=0; j<users.length; j++) {
7708                            IIntentReceiver finisher = null;
7709                            if (i == ris.size()-1 && j == users.length-1) {
7710                                finisher = new IIntentReceiver.Stub() {
7711                                    public void performReceive(Intent intent, int resultCode,
7712                                            String data, Bundle extras, boolean ordered,
7713                                            boolean sticky, int sendingUser) {
7714                                        // The raw IIntentReceiver interface is called
7715                                        // with the AM lock held, so redispatch to
7716                                        // execute our code without the lock.
7717                                        mHandler.post(new Runnable() {
7718                                            public void run() {
7719                                                synchronized (ActivityManagerService.this) {
7720                                                    mDidUpdate = true;
7721                                                }
7722                                                writeLastDonePreBootReceivers(doneReceivers);
7723                                                showBootMessage(mContext.getText(
7724                                                        R.string.android_upgrading_complete),
7725                                                        false);
7726                                                systemReady(goingCallback);
7727                                            }
7728                                        });
7729                                    }
7730                                };
7731                            }
7732                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7733                                    + " for user " + users[j]);
7734                            broadcastIntentLocked(null, null, intent, null, finisher,
7735                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7736                                    users[j]);
7737                            if (finisher != null) {
7738                                mWaitingUpdate = true;
7739                            }
7740                        }
7741                    }
7742                }
7743                if (mWaitingUpdate) {
7744                    return;
7745                }
7746                mDidUpdate = true;
7747            }
7748
7749            mSystemReady = true;
7750            if (!mStartRunning) {
7751                return;
7752            }
7753        }
7754
7755        ArrayList<ProcessRecord> procsToKill = null;
7756        synchronized(mPidsSelfLocked) {
7757            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7758                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7759                if (!isAllowedWhileBooting(proc.info)){
7760                    if (procsToKill == null) {
7761                        procsToKill = new ArrayList<ProcessRecord>();
7762                    }
7763                    procsToKill.add(proc);
7764                }
7765            }
7766        }
7767
7768        synchronized(this) {
7769            if (procsToKill != null) {
7770                for (int i=procsToKill.size()-1; i>=0; i--) {
7771                    ProcessRecord proc = procsToKill.get(i);
7772                    Slog.i(TAG, "Removing system update proc: " + proc);
7773                    removeProcessLocked(proc, true, false, "system update done");
7774                }
7775            }
7776
7777            // Now that we have cleaned up any update processes, we
7778            // are ready to start launching real processes and know that
7779            // we won't trample on them any more.
7780            mProcessesReady = true;
7781        }
7782
7783        Slog.i(TAG, "System now ready");
7784        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7785            SystemClock.uptimeMillis());
7786
7787        synchronized(this) {
7788            // Make sure we have no pre-ready processes sitting around.
7789
7790            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7791                ResolveInfo ri = mContext.getPackageManager()
7792                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7793                                STOCK_PM_FLAGS);
7794                CharSequence errorMsg = null;
7795                if (ri != null) {
7796                    ActivityInfo ai = ri.activityInfo;
7797                    ApplicationInfo app = ai.applicationInfo;
7798                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7799                        mTopAction = Intent.ACTION_FACTORY_TEST;
7800                        mTopData = null;
7801                        mTopComponent = new ComponentName(app.packageName,
7802                                ai.name);
7803                    } else {
7804                        errorMsg = mContext.getResources().getText(
7805                                com.android.internal.R.string.factorytest_not_system);
7806                    }
7807                } else {
7808                    errorMsg = mContext.getResources().getText(
7809                            com.android.internal.R.string.factorytest_no_action);
7810                }
7811                if (errorMsg != null) {
7812                    mTopAction = null;
7813                    mTopData = null;
7814                    mTopComponent = null;
7815                    Message msg = Message.obtain();
7816                    msg.what = SHOW_FACTORY_ERROR_MSG;
7817                    msg.getData().putCharSequence("msg", errorMsg);
7818                    mHandler.sendMessage(msg);
7819                }
7820            }
7821        }
7822
7823        retrieveSettings();
7824
7825        if (goingCallback != null) goingCallback.run();
7826
7827        synchronized (this) {
7828            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7829                try {
7830                    List apps = AppGlobals.getPackageManager().
7831                        getPersistentApplications(STOCK_PM_FLAGS);
7832                    if (apps != null) {
7833                        int N = apps.size();
7834                        int i;
7835                        for (i=0; i<N; i++) {
7836                            ApplicationInfo info
7837                                = (ApplicationInfo)apps.get(i);
7838                            if (info != null &&
7839                                    !info.packageName.equals("android")) {
7840                                addAppLocked(info, false);
7841                            }
7842                        }
7843                    }
7844                } catch (RemoteException ex) {
7845                    // pm is in same process, this will never happen.
7846                }
7847            }
7848
7849            // Start up initial activity.
7850            mBooting = true;
7851
7852            try {
7853                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7854                    Message msg = Message.obtain();
7855                    msg.what = SHOW_UID_ERROR_MSG;
7856                    mHandler.sendMessage(msg);
7857                }
7858            } catch (RemoteException e) {
7859            }
7860
7861            long ident = Binder.clearCallingIdentity();
7862            try {
7863                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7864                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7865                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7866                broadcastIntentLocked(null, null, intent,
7867                        null, null, 0, null, null, null,
7868                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7869            } finally {
7870                Binder.restoreCallingIdentity(ident);
7871            }
7872            mMainStack.resumeTopActivityLocked(null);
7873            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7874        }
7875    }
7876
7877    private boolean makeAppCrashingLocked(ProcessRecord app,
7878            String shortMsg, String longMsg, String stackTrace) {
7879        app.crashing = true;
7880        app.crashingReport = generateProcessError(app,
7881                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7882        startAppProblemLocked(app);
7883        app.stopFreezingAllLocked();
7884        return handleAppCrashLocked(app);
7885    }
7886
7887    private void makeAppNotRespondingLocked(ProcessRecord app,
7888            String activity, String shortMsg, String longMsg) {
7889        app.notResponding = true;
7890        app.notRespondingReport = generateProcessError(app,
7891                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7892                activity, shortMsg, longMsg, null);
7893        startAppProblemLocked(app);
7894        app.stopFreezingAllLocked();
7895    }
7896
7897    /**
7898     * Generate a process error record, suitable for attachment to a ProcessRecord.
7899     *
7900     * @param app The ProcessRecord in which the error occurred.
7901     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7902     *                      ActivityManager.AppErrorStateInfo
7903     * @param activity The activity associated with the crash, if known.
7904     * @param shortMsg Short message describing the crash.
7905     * @param longMsg Long message describing the crash.
7906     * @param stackTrace Full crash stack trace, may be null.
7907     *
7908     * @return Returns a fully-formed AppErrorStateInfo record.
7909     */
7910    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7911            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7912        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7913
7914        report.condition = condition;
7915        report.processName = app.processName;
7916        report.pid = app.pid;
7917        report.uid = app.info.uid;
7918        report.tag = activity;
7919        report.shortMsg = shortMsg;
7920        report.longMsg = longMsg;
7921        report.stackTrace = stackTrace;
7922
7923        return report;
7924    }
7925
7926    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7927        synchronized (this) {
7928            app.crashing = false;
7929            app.crashingReport = null;
7930            app.notResponding = false;
7931            app.notRespondingReport = null;
7932            if (app.anrDialog == fromDialog) {
7933                app.anrDialog = null;
7934            }
7935            if (app.waitDialog == fromDialog) {
7936                app.waitDialog = null;
7937            }
7938            if (app.pid > 0 && app.pid != MY_PID) {
7939                handleAppCrashLocked(app);
7940                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7941                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7942                        app.processName, app.setAdj, "user's request after error");
7943                Process.killProcessQuiet(app.pid);
7944            }
7945        }
7946    }
7947
7948    private boolean handleAppCrashLocked(ProcessRecord app) {
7949        if (mHeadless) {
7950            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7951            return false;
7952        }
7953        long now = SystemClock.uptimeMillis();
7954
7955        Long crashTime;
7956        if (!app.isolated) {
7957            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7958        } else {
7959            crashTime = null;
7960        }
7961        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7962            // This process loses!
7963            Slog.w(TAG, "Process " + app.info.processName
7964                    + " has crashed too many times: killing!");
7965            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7966                    app.info.processName, app.uid);
7967            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7968                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7969                if (r.app == app) {
7970                    Slog.w(TAG, "  Force finishing activity "
7971                        + r.intent.getComponent().flattenToShortString());
7972                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7973                            null, "crashed", false);
7974                }
7975            }
7976            if (!app.persistent) {
7977                // We don't want to start this process again until the user
7978                // explicitly does so...  but for persistent process, we really
7979                // need to keep it running.  If a persistent process is actually
7980                // repeatedly crashing, then badness for everyone.
7981                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7982                        app.info.processName);
7983                if (!app.isolated) {
7984                    // XXX We don't have a way to mark isolated processes
7985                    // as bad, since they don't have a peristent identity.
7986                    mBadProcesses.put(app.info.processName, app.uid, now);
7987                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7988                }
7989                app.bad = true;
7990                app.removed = true;
7991                // Don't let services in this process be restarted and potentially
7992                // annoy the user repeatedly.  Unless it is persistent, since those
7993                // processes run critical code.
7994                removeProcessLocked(app, false, false, "crash");
7995                mMainStack.resumeTopActivityLocked(null);
7996                return false;
7997            }
7998            mMainStack.resumeTopActivityLocked(null);
7999        } else {
8000            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8001            if (r != null && r.app == app) {
8002                // If the top running activity is from this crashing
8003                // process, then terminate it to avoid getting in a loop.
8004                Slog.w(TAG, "  Force finishing activity "
8005                        + r.intent.getComponent().flattenToShortString());
8006                int index = mMainStack.indexOfActivityLocked(r);
8007                r.stack.finishActivityLocked(r, index,
8008                        Activity.RESULT_CANCELED, null, "crashed", false);
8009                // Also terminate any activities below it that aren't yet
8010                // stopped, to avoid a situation where one will get
8011                // re-start our crashing activity once it gets resumed again.
8012                index--;
8013                if (index >= 0) {
8014                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8015                    if (r.state == ActivityState.RESUMED
8016                            || r.state == ActivityState.PAUSING
8017                            || r.state == ActivityState.PAUSED) {
8018                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8019                            Slog.w(TAG, "  Force finishing activity "
8020                                    + r.intent.getComponent().flattenToShortString());
8021                            r.stack.finishActivityLocked(r, index,
8022                                    Activity.RESULT_CANCELED, null, "crashed", false);
8023                        }
8024                    }
8025                }
8026            }
8027        }
8028
8029        // Bump up the crash count of any services currently running in the proc.
8030        if (app.services.size() != 0) {
8031            // Any services running in the application need to be placed
8032            // back in the pending list.
8033            Iterator<ServiceRecord> it = app.services.iterator();
8034            while (it.hasNext()) {
8035                ServiceRecord sr = it.next();
8036                sr.crashCount++;
8037            }
8038        }
8039
8040        // If the crashing process is what we consider to be the "home process" and it has been
8041        // replaced by a third-party app, clear the package preferred activities from packages
8042        // with a home activity running in the process to prevent a repeatedly crashing app
8043        // from blocking the user to manually clear the list.
8044        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8045                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8046            Iterator it = mHomeProcess.activities.iterator();
8047            while (it.hasNext()) {
8048                ActivityRecord r = (ActivityRecord)it.next();
8049                if (r.isHomeActivity) {
8050                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8051                    try {
8052                        ActivityThread.getPackageManager()
8053                                .clearPackagePreferredActivities(r.packageName);
8054                    } catch (RemoteException c) {
8055                        // pm is in same process, this will never happen.
8056                    }
8057                }
8058            }
8059        }
8060
8061        if (!app.isolated) {
8062            // XXX Can't keep track of crash times for isolated processes,
8063            // because they don't have a perisistent identity.
8064            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8065        }
8066
8067        return true;
8068    }
8069
8070    void startAppProblemLocked(ProcessRecord app) {
8071        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8072                mContext, app.info.packageName, app.info.flags);
8073        skipCurrentReceiverLocked(app);
8074    }
8075
8076    void skipCurrentReceiverLocked(ProcessRecord app) {
8077        for (BroadcastQueue queue : mBroadcastQueues) {
8078            queue.skipCurrentReceiverLocked(app);
8079        }
8080    }
8081
8082    /**
8083     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8084     * The application process will exit immediately after this call returns.
8085     * @param app object of the crashing app, null for the system server
8086     * @param crashInfo describing the exception
8087     */
8088    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8089        ProcessRecord r = findAppProcess(app, "Crash");
8090        final String processName = app == null ? "system_server"
8091                : (r == null ? "unknown" : r.processName);
8092
8093        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8094                processName,
8095                r == null ? -1 : r.info.flags,
8096                crashInfo.exceptionClassName,
8097                crashInfo.exceptionMessage,
8098                crashInfo.throwFileName,
8099                crashInfo.throwLineNumber);
8100
8101        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8102
8103        crashApplication(r, crashInfo);
8104    }
8105
8106    public void handleApplicationStrictModeViolation(
8107            IBinder app,
8108            int violationMask,
8109            StrictMode.ViolationInfo info) {
8110        ProcessRecord r = findAppProcess(app, "StrictMode");
8111        if (r == null) {
8112            return;
8113        }
8114
8115        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8116            Integer stackFingerprint = info.hashCode();
8117            boolean logIt = true;
8118            synchronized (mAlreadyLoggedViolatedStacks) {
8119                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8120                    logIt = false;
8121                    // TODO: sub-sample into EventLog for these, with
8122                    // the info.durationMillis?  Then we'd get
8123                    // the relative pain numbers, without logging all
8124                    // the stack traces repeatedly.  We'd want to do
8125                    // likewise in the client code, which also does
8126                    // dup suppression, before the Binder call.
8127                } else {
8128                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8129                        mAlreadyLoggedViolatedStacks.clear();
8130                    }
8131                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8132                }
8133            }
8134            if (logIt) {
8135                logStrictModeViolationToDropBox(r, info);
8136            }
8137        }
8138
8139        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8140            AppErrorResult result = new AppErrorResult();
8141            synchronized (this) {
8142                final long origId = Binder.clearCallingIdentity();
8143
8144                Message msg = Message.obtain();
8145                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8146                HashMap<String, Object> data = new HashMap<String, Object>();
8147                data.put("result", result);
8148                data.put("app", r);
8149                data.put("violationMask", violationMask);
8150                data.put("info", info);
8151                msg.obj = data;
8152                mHandler.sendMessage(msg);
8153
8154                Binder.restoreCallingIdentity(origId);
8155            }
8156            int res = result.get();
8157            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8158        }
8159    }
8160
8161    // Depending on the policy in effect, there could be a bunch of
8162    // these in quick succession so we try to batch these together to
8163    // minimize disk writes, number of dropbox entries, and maximize
8164    // compression, by having more fewer, larger records.
8165    private void logStrictModeViolationToDropBox(
8166            ProcessRecord process,
8167            StrictMode.ViolationInfo info) {
8168        if (info == null) {
8169            return;
8170        }
8171        final boolean isSystemApp = process == null ||
8172                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8173                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8174        final String processName = process == null ? "unknown" : process.processName;
8175        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8176        final DropBoxManager dbox = (DropBoxManager)
8177                mContext.getSystemService(Context.DROPBOX_SERVICE);
8178
8179        // Exit early if the dropbox isn't configured to accept this report type.
8180        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8181
8182        boolean bufferWasEmpty;
8183        boolean needsFlush;
8184        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8185        synchronized (sb) {
8186            bufferWasEmpty = sb.length() == 0;
8187            appendDropBoxProcessHeaders(process, processName, sb);
8188            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8189            sb.append("System-App: ").append(isSystemApp).append("\n");
8190            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8191            if (info.violationNumThisLoop != 0) {
8192                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8193            }
8194            if (info.numAnimationsRunning != 0) {
8195                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8196            }
8197            if (info.broadcastIntentAction != null) {
8198                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8199            }
8200            if (info.durationMillis != -1) {
8201                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8202            }
8203            if (info.numInstances != -1) {
8204                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8205            }
8206            if (info.tags != null) {
8207                for (String tag : info.tags) {
8208                    sb.append("Span-Tag: ").append(tag).append("\n");
8209                }
8210            }
8211            sb.append("\n");
8212            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8213                sb.append(info.crashInfo.stackTrace);
8214            }
8215            sb.append("\n");
8216
8217            // Only buffer up to ~64k.  Various logging bits truncate
8218            // things at 128k.
8219            needsFlush = (sb.length() > 64 * 1024);
8220        }
8221
8222        // Flush immediately if the buffer's grown too large, or this
8223        // is a non-system app.  Non-system apps are isolated with a
8224        // different tag & policy and not batched.
8225        //
8226        // Batching is useful during internal testing with
8227        // StrictMode settings turned up high.  Without batching,
8228        // thousands of separate files could be created on boot.
8229        if (!isSystemApp || needsFlush) {
8230            new Thread("Error dump: " + dropboxTag) {
8231                @Override
8232                public void run() {
8233                    String report;
8234                    synchronized (sb) {
8235                        report = sb.toString();
8236                        sb.delete(0, sb.length());
8237                        sb.trimToSize();
8238                    }
8239                    if (report.length() != 0) {
8240                        dbox.addText(dropboxTag, report);
8241                    }
8242                }
8243            }.start();
8244            return;
8245        }
8246
8247        // System app batching:
8248        if (!bufferWasEmpty) {
8249            // An existing dropbox-writing thread is outstanding, so
8250            // we don't need to start it up.  The existing thread will
8251            // catch the buffer appends we just did.
8252            return;
8253        }
8254
8255        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8256        // (After this point, we shouldn't access AMS internal data structures.)
8257        new Thread("Error dump: " + dropboxTag) {
8258            @Override
8259            public void run() {
8260                // 5 second sleep to let stacks arrive and be batched together
8261                try {
8262                    Thread.sleep(5000);  // 5 seconds
8263                } catch (InterruptedException e) {}
8264
8265                String errorReport;
8266                synchronized (mStrictModeBuffer) {
8267                    errorReport = mStrictModeBuffer.toString();
8268                    if (errorReport.length() == 0) {
8269                        return;
8270                    }
8271                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8272                    mStrictModeBuffer.trimToSize();
8273                }
8274                dbox.addText(dropboxTag, errorReport);
8275            }
8276        }.start();
8277    }
8278
8279    /**
8280     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8281     * @param app object of the crashing app, null for the system server
8282     * @param tag reported by the caller
8283     * @param crashInfo describing the context of the error
8284     * @return true if the process should exit immediately (WTF is fatal)
8285     */
8286    public boolean handleApplicationWtf(IBinder app, String tag,
8287            ApplicationErrorReport.CrashInfo crashInfo) {
8288        ProcessRecord r = findAppProcess(app, "WTF");
8289        final String processName = app == null ? "system_server"
8290                : (r == null ? "unknown" : r.processName);
8291
8292        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8293                processName,
8294                r == null ? -1 : r.info.flags,
8295                tag, crashInfo.exceptionMessage);
8296
8297        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8298
8299        if (r != null && r.pid != Process.myPid() &&
8300                Settings.Secure.getInt(mContext.getContentResolver(),
8301                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8302            crashApplication(r, crashInfo);
8303            return true;
8304        } else {
8305            return false;
8306        }
8307    }
8308
8309    /**
8310     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8311     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8312     */
8313    private ProcessRecord findAppProcess(IBinder app, String reason) {
8314        if (app == null) {
8315            return null;
8316        }
8317
8318        synchronized (this) {
8319            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8320                final int NA = apps.size();
8321                for (int ia=0; ia<NA; ia++) {
8322                    ProcessRecord p = apps.valueAt(ia);
8323                    if (p.thread != null && p.thread.asBinder() == app) {
8324                        return p;
8325                    }
8326                }
8327            }
8328
8329            Slog.w(TAG, "Can't find mystery application for " + reason
8330                    + " from pid=" + Binder.getCallingPid()
8331                    + " uid=" + Binder.getCallingUid() + ": " + app);
8332            return null;
8333        }
8334    }
8335
8336    /**
8337     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8338     * to append various headers to the dropbox log text.
8339     */
8340    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8341            StringBuilder sb) {
8342        // Watchdog thread ends up invoking this function (with
8343        // a null ProcessRecord) to add the stack file to dropbox.
8344        // Do not acquire a lock on this (am) in such cases, as it
8345        // could cause a potential deadlock, if and when watchdog
8346        // is invoked due to unavailability of lock on am and it
8347        // would prevent watchdog from killing system_server.
8348        if (process == null) {
8349            sb.append("Process: ").append(processName).append("\n");
8350            return;
8351        }
8352        // Note: ProcessRecord 'process' is guarded by the service
8353        // instance.  (notably process.pkgList, which could otherwise change
8354        // concurrently during execution of this method)
8355        synchronized (this) {
8356            sb.append("Process: ").append(processName).append("\n");
8357            int flags = process.info.flags;
8358            IPackageManager pm = AppGlobals.getPackageManager();
8359            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8360            for (String pkg : process.pkgList) {
8361                sb.append("Package: ").append(pkg);
8362                try {
8363                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8364                    if (pi != null) {
8365                        sb.append(" v").append(pi.versionCode);
8366                        if (pi.versionName != null) {
8367                            sb.append(" (").append(pi.versionName).append(")");
8368                        }
8369                    }
8370                } catch (RemoteException e) {
8371                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8372                }
8373                sb.append("\n");
8374            }
8375        }
8376    }
8377
8378    private static String processClass(ProcessRecord process) {
8379        if (process == null || process.pid == MY_PID) {
8380            return "system_server";
8381        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8382            return "system_app";
8383        } else {
8384            return "data_app";
8385        }
8386    }
8387
8388    /**
8389     * Write a description of an error (crash, WTF, ANR) to the drop box.
8390     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8391     * @param process which caused the error, null means the system server
8392     * @param activity which triggered the error, null if unknown
8393     * @param parent activity related to the error, null if unknown
8394     * @param subject line related to the error, null if absent
8395     * @param report in long form describing the error, null if absent
8396     * @param logFile to include in the report, null if none
8397     * @param crashInfo giving an application stack trace, null if absent
8398     */
8399    public void addErrorToDropBox(String eventType,
8400            ProcessRecord process, String processName, ActivityRecord activity,
8401            ActivityRecord parent, String subject,
8402            final String report, final File logFile,
8403            final ApplicationErrorReport.CrashInfo crashInfo) {
8404        // NOTE -- this must never acquire the ActivityManagerService lock,
8405        // otherwise the watchdog may be prevented from resetting the system.
8406
8407        final String dropboxTag = processClass(process) + "_" + eventType;
8408        final DropBoxManager dbox = (DropBoxManager)
8409                mContext.getSystemService(Context.DROPBOX_SERVICE);
8410
8411        // Exit early if the dropbox isn't configured to accept this report type.
8412        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8413
8414        final StringBuilder sb = new StringBuilder(1024);
8415        appendDropBoxProcessHeaders(process, processName, sb);
8416        if (activity != null) {
8417            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8418        }
8419        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8420            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8421        }
8422        if (parent != null && parent != activity) {
8423            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8424        }
8425        if (subject != null) {
8426            sb.append("Subject: ").append(subject).append("\n");
8427        }
8428        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8429        if (Debug.isDebuggerConnected()) {
8430            sb.append("Debugger: Connected\n");
8431        }
8432        sb.append("\n");
8433
8434        // Do the rest in a worker thread to avoid blocking the caller on I/O
8435        // (After this point, we shouldn't access AMS internal data structures.)
8436        Thread worker = new Thread("Error dump: " + dropboxTag) {
8437            @Override
8438            public void run() {
8439                if (report != null) {
8440                    sb.append(report);
8441                }
8442                if (logFile != null) {
8443                    try {
8444                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8445                    } catch (IOException e) {
8446                        Slog.e(TAG, "Error reading " + logFile, e);
8447                    }
8448                }
8449                if (crashInfo != null && crashInfo.stackTrace != null) {
8450                    sb.append(crashInfo.stackTrace);
8451                }
8452
8453                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8454                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8455                if (lines > 0) {
8456                    sb.append("\n");
8457
8458                    // Merge several logcat streams, and take the last N lines
8459                    InputStreamReader input = null;
8460                    try {
8461                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8462                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8463                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8464
8465                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8466                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8467                        input = new InputStreamReader(logcat.getInputStream());
8468
8469                        int num;
8470                        char[] buf = new char[8192];
8471                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8472                    } catch (IOException e) {
8473                        Slog.e(TAG, "Error running logcat", e);
8474                    } finally {
8475                        if (input != null) try { input.close(); } catch (IOException e) {}
8476                    }
8477                }
8478
8479                dbox.addText(dropboxTag, sb.toString());
8480            }
8481        };
8482
8483        if (process == null) {
8484            // If process is null, we are being called from some internal code
8485            // and may be about to die -- run this synchronously.
8486            worker.run();
8487        } else {
8488            worker.start();
8489        }
8490    }
8491
8492    /**
8493     * Bring up the "unexpected error" dialog box for a crashing app.
8494     * Deal with edge cases (intercepts from instrumented applications,
8495     * ActivityController, error intent receivers, that sort of thing).
8496     * @param r the application crashing
8497     * @param crashInfo describing the failure
8498     */
8499    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8500        long timeMillis = System.currentTimeMillis();
8501        String shortMsg = crashInfo.exceptionClassName;
8502        String longMsg = crashInfo.exceptionMessage;
8503        String stackTrace = crashInfo.stackTrace;
8504        if (shortMsg != null && longMsg != null) {
8505            longMsg = shortMsg + ": " + longMsg;
8506        } else if (shortMsg != null) {
8507            longMsg = shortMsg;
8508        }
8509
8510        AppErrorResult result = new AppErrorResult();
8511        synchronized (this) {
8512            if (mController != null) {
8513                try {
8514                    String name = r != null ? r.processName : null;
8515                    int pid = r != null ? r.pid : Binder.getCallingPid();
8516                    if (!mController.appCrashed(name, pid,
8517                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8518                        Slog.w(TAG, "Force-killing crashed app " + name
8519                                + " at watcher's request");
8520                        Process.killProcess(pid);
8521                        return;
8522                    }
8523                } catch (RemoteException e) {
8524                    mController = null;
8525                }
8526            }
8527
8528            final long origId = Binder.clearCallingIdentity();
8529
8530            // If this process is running instrumentation, finish it.
8531            if (r != null && r.instrumentationClass != null) {
8532                Slog.w(TAG, "Error in app " + r.processName
8533                      + " running instrumentation " + r.instrumentationClass + ":");
8534                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8535                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8536                Bundle info = new Bundle();
8537                info.putString("shortMsg", shortMsg);
8538                info.putString("longMsg", longMsg);
8539                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8540                Binder.restoreCallingIdentity(origId);
8541                return;
8542            }
8543
8544            // If we can't identify the process or it's already exceeded its crash quota,
8545            // quit right away without showing a crash dialog.
8546            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8547                Binder.restoreCallingIdentity(origId);
8548                return;
8549            }
8550
8551            Message msg = Message.obtain();
8552            msg.what = SHOW_ERROR_MSG;
8553            HashMap data = new HashMap();
8554            data.put("result", result);
8555            data.put("app", r);
8556            msg.obj = data;
8557            mHandler.sendMessage(msg);
8558
8559            Binder.restoreCallingIdentity(origId);
8560        }
8561
8562        int res = result.get();
8563
8564        Intent appErrorIntent = null;
8565        synchronized (this) {
8566            if (r != null && !r.isolated) {
8567                // XXX Can't keep track of crash time for isolated processes,
8568                // since they don't have a persistent identity.
8569                mProcessCrashTimes.put(r.info.processName, r.uid,
8570                        SystemClock.uptimeMillis());
8571            }
8572            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8573                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8574            }
8575        }
8576
8577        if (appErrorIntent != null) {
8578            try {
8579                mContext.startActivity(appErrorIntent);
8580            } catch (ActivityNotFoundException e) {
8581                Slog.w(TAG, "bug report receiver dissappeared", e);
8582            }
8583        }
8584    }
8585
8586    Intent createAppErrorIntentLocked(ProcessRecord r,
8587            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8588        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8589        if (report == null) {
8590            return null;
8591        }
8592        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8593        result.setComponent(r.errorReportReceiver);
8594        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8595        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8596        return result;
8597    }
8598
8599    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8600            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8601        if (r.errorReportReceiver == null) {
8602            return null;
8603        }
8604
8605        if (!r.crashing && !r.notResponding) {
8606            return null;
8607        }
8608
8609        ApplicationErrorReport report = new ApplicationErrorReport();
8610        report.packageName = r.info.packageName;
8611        report.installerPackageName = r.errorReportReceiver.getPackageName();
8612        report.processName = r.processName;
8613        report.time = timeMillis;
8614        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8615
8616        if (r.crashing) {
8617            report.type = ApplicationErrorReport.TYPE_CRASH;
8618            report.crashInfo = crashInfo;
8619        } else if (r.notResponding) {
8620            report.type = ApplicationErrorReport.TYPE_ANR;
8621            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8622
8623            report.anrInfo.activity = r.notRespondingReport.tag;
8624            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8625            report.anrInfo.info = r.notRespondingReport.longMsg;
8626        }
8627
8628        return report;
8629    }
8630
8631    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8632        enforceNotIsolatedCaller("getProcessesInErrorState");
8633        // assume our apps are happy - lazy create the list
8634        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8635
8636        final boolean allUsers = ActivityManager.checkUidPermission(
8637                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8638                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8639        int userId = UserHandle.getUserId(Binder.getCallingUid());
8640
8641        synchronized (this) {
8642
8643            // iterate across all processes
8644            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8645                ProcessRecord app = mLruProcesses.get(i);
8646                if (!allUsers && app.userId != userId) {
8647                    continue;
8648                }
8649                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8650                    // This one's in trouble, so we'll generate a report for it
8651                    // crashes are higher priority (in case there's a crash *and* an anr)
8652                    ActivityManager.ProcessErrorStateInfo report = null;
8653                    if (app.crashing) {
8654                        report = app.crashingReport;
8655                    } else if (app.notResponding) {
8656                        report = app.notRespondingReport;
8657                    }
8658
8659                    if (report != null) {
8660                        if (errList == null) {
8661                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8662                        }
8663                        errList.add(report);
8664                    } else {
8665                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8666                                " crashing = " + app.crashing +
8667                                " notResponding = " + app.notResponding);
8668                    }
8669                }
8670            }
8671        }
8672
8673        return errList;
8674    }
8675
8676    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8677        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8678            if (currApp != null) {
8679                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8680            }
8681            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8682        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8683            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8684        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8685            if (currApp != null) {
8686                currApp.lru = 0;
8687            }
8688            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8689        } else if (adj >= ProcessList.SERVICE_ADJ) {
8690            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8691        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8692            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8693        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8694            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8695        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8696            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8697        } else {
8698            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8699        }
8700    }
8701
8702    private void fillInProcMemInfo(ProcessRecord app,
8703            ActivityManager.RunningAppProcessInfo outInfo) {
8704        outInfo.pid = app.pid;
8705        outInfo.uid = app.info.uid;
8706        if (mHeavyWeightProcess == app) {
8707            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8708        }
8709        if (app.persistent) {
8710            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8711        }
8712        if (app.hasActivities) {
8713            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8714        }
8715        outInfo.lastTrimLevel = app.trimMemoryLevel;
8716        int adj = app.curAdj;
8717        outInfo.importance = oomAdjToImportance(adj, outInfo);
8718        outInfo.importanceReasonCode = app.adjTypeCode;
8719    }
8720
8721    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8722        enforceNotIsolatedCaller("getRunningAppProcesses");
8723        // Lazy instantiation of list
8724        List<ActivityManager.RunningAppProcessInfo> runList = null;
8725        final boolean allUsers = ActivityManager.checkUidPermission(
8726                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8727                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8728        int userId = UserHandle.getUserId(Binder.getCallingUid());
8729        synchronized (this) {
8730            // Iterate across all processes
8731            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8732                ProcessRecord app = mLruProcesses.get(i);
8733                if (!allUsers && app.userId != userId) {
8734                    continue;
8735                }
8736                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8737                    // Generate process state info for running application
8738                    ActivityManager.RunningAppProcessInfo currApp =
8739                        new ActivityManager.RunningAppProcessInfo(app.processName,
8740                                app.pid, app.getPackageList());
8741                    fillInProcMemInfo(app, currApp);
8742                    if (app.adjSource instanceof ProcessRecord) {
8743                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8744                        currApp.importanceReasonImportance = oomAdjToImportance(
8745                                app.adjSourceOom, null);
8746                    } else if (app.adjSource instanceof ActivityRecord) {
8747                        ActivityRecord r = (ActivityRecord)app.adjSource;
8748                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8749                    }
8750                    if (app.adjTarget instanceof ComponentName) {
8751                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8752                    }
8753                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8754                    //        + " lru=" + currApp.lru);
8755                    if (runList == null) {
8756                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8757                    }
8758                    runList.add(currApp);
8759                }
8760            }
8761        }
8762        return runList;
8763    }
8764
8765    public List<ApplicationInfo> getRunningExternalApplications() {
8766        enforceNotIsolatedCaller("getRunningExternalApplications");
8767        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8768        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8769        if (runningApps != null && runningApps.size() > 0) {
8770            Set<String> extList = new HashSet<String>();
8771            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8772                if (app.pkgList != null) {
8773                    for (String pkg : app.pkgList) {
8774                        extList.add(pkg);
8775                    }
8776                }
8777            }
8778            IPackageManager pm = AppGlobals.getPackageManager();
8779            for (String pkg : extList) {
8780                try {
8781                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8782                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8783                        retList.add(info);
8784                    }
8785                } catch (RemoteException e) {
8786                }
8787            }
8788        }
8789        return retList;
8790    }
8791
8792    @Override
8793    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8794        enforceNotIsolatedCaller("getMyMemoryState");
8795        synchronized (this) {
8796            ProcessRecord proc;
8797            synchronized (mPidsSelfLocked) {
8798                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8799            }
8800            fillInProcMemInfo(proc, outInfo);
8801        }
8802    }
8803
8804    @Override
8805    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8806        if (checkCallingPermission(android.Manifest.permission.DUMP)
8807                != PackageManager.PERMISSION_GRANTED) {
8808            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8809                    + Binder.getCallingPid()
8810                    + ", uid=" + Binder.getCallingUid()
8811                    + " without permission "
8812                    + android.Manifest.permission.DUMP);
8813            return;
8814        }
8815
8816        boolean dumpAll = false;
8817        boolean dumpClient = false;
8818        String dumpPackage = null;
8819
8820        int opti = 0;
8821        while (opti < args.length) {
8822            String opt = args[opti];
8823            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8824                break;
8825            }
8826            opti++;
8827            if ("-a".equals(opt)) {
8828                dumpAll = true;
8829            } else if ("-c".equals(opt)) {
8830                dumpClient = true;
8831            } else if ("-h".equals(opt)) {
8832                pw.println("Activity manager dump options:");
8833                pw.println("  [-a] [-c] [-h] [cmd] ...");
8834                pw.println("  cmd may be one of:");
8835                pw.println("    a[ctivities]: activity stack state");
8836                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8837                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8838                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8839                pw.println("    o[om]: out of memory management");
8840                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8841                pw.println("    provider [COMP_SPEC]: provider client-side state");
8842                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8843                pw.println("    service [COMP_SPEC]: service client-side state");
8844                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8845                pw.println("    all: dump all activities");
8846                pw.println("    top: dump the top activity");
8847                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8848                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8849                pw.println("    a partial substring in a component name, a");
8850                pw.println("    hex object identifier.");
8851                pw.println("  -a: include all available server state.");
8852                pw.println("  -c: include client state.");
8853                return;
8854            } else {
8855                pw.println("Unknown argument: " + opt + "; use -h for help");
8856            }
8857        }
8858
8859        long origId = Binder.clearCallingIdentity();
8860        boolean more = false;
8861        // Is the caller requesting to dump a particular piece of data?
8862        if (opti < args.length) {
8863            String cmd = args[opti];
8864            opti++;
8865            if ("activities".equals(cmd) || "a".equals(cmd)) {
8866                synchronized (this) {
8867                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8868                }
8869            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8870                String[] newArgs;
8871                String name;
8872                if (opti >= args.length) {
8873                    name = null;
8874                    newArgs = EMPTY_STRING_ARRAY;
8875                } else {
8876                    name = args[opti];
8877                    opti++;
8878                    newArgs = new String[args.length - opti];
8879                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8880                            args.length - opti);
8881                }
8882                synchronized (this) {
8883                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8884                }
8885            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8886                String[] newArgs;
8887                String name;
8888                if (opti >= args.length) {
8889                    name = null;
8890                    newArgs = EMPTY_STRING_ARRAY;
8891                } else {
8892                    name = args[opti];
8893                    opti++;
8894                    newArgs = new String[args.length - opti];
8895                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8896                            args.length - opti);
8897                }
8898                synchronized (this) {
8899                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8900                }
8901            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8902                String[] newArgs;
8903                String name;
8904                if (opti >= args.length) {
8905                    name = null;
8906                    newArgs = EMPTY_STRING_ARRAY;
8907                } else {
8908                    name = args[opti];
8909                    opti++;
8910                    newArgs = new String[args.length - opti];
8911                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8912                            args.length - opti);
8913                }
8914                synchronized (this) {
8915                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8916                }
8917            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8918                synchronized (this) {
8919                    dumpOomLocked(fd, pw, args, opti, true);
8920                }
8921            } else if ("provider".equals(cmd)) {
8922                String[] newArgs;
8923                String name;
8924                if (opti >= args.length) {
8925                    name = null;
8926                    newArgs = EMPTY_STRING_ARRAY;
8927                } else {
8928                    name = args[opti];
8929                    opti++;
8930                    newArgs = new String[args.length - opti];
8931                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8932                }
8933                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8934                    pw.println("No providers match: " + name);
8935                    pw.println("Use -h for help.");
8936                }
8937            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8938                synchronized (this) {
8939                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8940                }
8941            } else if ("service".equals(cmd)) {
8942                String[] newArgs;
8943                String name;
8944                if (opti >= args.length) {
8945                    name = null;
8946                    newArgs = EMPTY_STRING_ARRAY;
8947                } else {
8948                    name = args[opti];
8949                    opti++;
8950                    newArgs = new String[args.length - opti];
8951                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8952                            args.length - opti);
8953                }
8954                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8955                    pw.println("No services match: " + name);
8956                    pw.println("Use -h for help.");
8957                }
8958            } else if ("package".equals(cmd)) {
8959                String[] newArgs;
8960                if (opti >= args.length) {
8961                    pw.println("package: no package name specified");
8962                    pw.println("Use -h for help.");
8963                } else {
8964                    dumpPackage = args[opti];
8965                    opti++;
8966                    newArgs = new String[args.length - opti];
8967                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8968                            args.length - opti);
8969                    args = newArgs;
8970                    opti = 0;
8971                    more = true;
8972                }
8973            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8974                synchronized (this) {
8975                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8976                }
8977            } else {
8978                // Dumping a single activity?
8979                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8980                    pw.println("Bad activity command, or no activities match: " + cmd);
8981                    pw.println("Use -h for help.");
8982                }
8983            }
8984            if (!more) {
8985                Binder.restoreCallingIdentity(origId);
8986                return;
8987            }
8988        }
8989
8990        // No piece of data specified, dump everything.
8991        synchronized (this) {
8992            boolean needSep;
8993            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8994            if (needSep) {
8995                pw.println(" ");
8996            }
8997            if (dumpAll) {
8998                pw.println("-------------------------------------------------------------------------------");
8999            }
9000            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9001            if (needSep) {
9002                pw.println(" ");
9003            }
9004            if (dumpAll) {
9005                pw.println("-------------------------------------------------------------------------------");
9006            }
9007            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9008            if (needSep) {
9009                pw.println(" ");
9010            }
9011            if (dumpAll) {
9012                pw.println("-------------------------------------------------------------------------------");
9013            }
9014            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9015            if (needSep) {
9016                pw.println(" ");
9017            }
9018            if (dumpAll) {
9019                pw.println("-------------------------------------------------------------------------------");
9020            }
9021            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9022            if (needSep) {
9023                pw.println(" ");
9024            }
9025            if (dumpAll) {
9026                pw.println("-------------------------------------------------------------------------------");
9027            }
9028            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9029        }
9030        Binder.restoreCallingIdentity(origId);
9031    }
9032
9033    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9034            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9035        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9036        pw.println("  Main stack:");
9037        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9038                dumpPackage);
9039        pw.println(" ");
9040        pw.println("  Running activities (most recent first):");
9041        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9042                dumpPackage);
9043        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9044            pw.println(" ");
9045            pw.println("  Activities waiting for another to become visible:");
9046            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9047                    !dumpAll, false, dumpPackage);
9048        }
9049        if (mMainStack.mStoppingActivities.size() > 0) {
9050            pw.println(" ");
9051            pw.println("  Activities waiting to stop:");
9052            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9053                    !dumpAll, false, dumpPackage);
9054        }
9055        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9056            pw.println(" ");
9057            pw.println("  Activities waiting to sleep:");
9058            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9059                    !dumpAll, false, dumpPackage);
9060        }
9061        if (mMainStack.mFinishingActivities.size() > 0) {
9062            pw.println(" ");
9063            pw.println("  Activities waiting to finish:");
9064            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9065                    !dumpAll, false, dumpPackage);
9066        }
9067
9068        pw.println(" ");
9069        if (mMainStack.mPausingActivity != null) {
9070            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9071        }
9072        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9073        pw.println("  mFocusedActivity: " + mFocusedActivity);
9074        if (dumpAll) {
9075            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9076            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9077            pw.println("  mDismissKeyguardOnNextActivity: "
9078                    + mMainStack.mDismissKeyguardOnNextActivity);
9079        }
9080
9081        if (mRecentTasks.size() > 0) {
9082            pw.println();
9083            pw.println("  Recent tasks:");
9084
9085            final int N = mRecentTasks.size();
9086            for (int i=0; i<N; i++) {
9087                TaskRecord tr = mRecentTasks.get(i);
9088                if (dumpPackage != null) {
9089                    if (tr.realActivity == null ||
9090                            !dumpPackage.equals(tr.realActivity)) {
9091                        continue;
9092                    }
9093                }
9094                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9095                        pw.println(tr);
9096                if (dumpAll) {
9097                    mRecentTasks.get(i).dump(pw, "    ");
9098                }
9099            }
9100        }
9101
9102        if (dumpAll) {
9103            pw.println(" ");
9104            pw.println("  mCurTask: " + mCurTask);
9105        }
9106
9107        return true;
9108    }
9109
9110    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9111            int opti, boolean dumpAll, String dumpPackage) {
9112        boolean needSep = false;
9113        int numPers = 0;
9114
9115        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9116
9117        if (dumpAll) {
9118            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9119                final int NA = procs.size();
9120                for (int ia=0; ia<NA; ia++) {
9121                    ProcessRecord r = procs.valueAt(ia);
9122                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9123                        continue;
9124                    }
9125                    if (!needSep) {
9126                        pw.println("  All known processes:");
9127                        needSep = true;
9128                    }
9129                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9130                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9131                        pw.print(" "); pw.println(r);
9132                    r.dump(pw, "    ");
9133                    if (r.persistent) {
9134                        numPers++;
9135                    }
9136                }
9137            }
9138        }
9139
9140        if (mIsolatedProcesses.size() > 0) {
9141            if (needSep) pw.println(" ");
9142            needSep = true;
9143            pw.println("  Isolated process list (sorted by uid):");
9144            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9145                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9146                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9147                    continue;
9148                }
9149                pw.println(String.format("%sIsolated #%2d: %s",
9150                        "    ", i, r.toString()));
9151            }
9152        }
9153
9154        if (mLruProcesses.size() > 0) {
9155            if (needSep) pw.println(" ");
9156            needSep = true;
9157            pw.println("  Process LRU list (sorted by oom_adj):");
9158            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9159                    "Proc", "PERS", false, dumpPackage);
9160            needSep = true;
9161        }
9162
9163        if (dumpAll) {
9164            synchronized (mPidsSelfLocked) {
9165                boolean printed = false;
9166                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9167                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9168                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9169                        continue;
9170                    }
9171                    if (!printed) {
9172                        if (needSep) pw.println(" ");
9173                        needSep = true;
9174                        pw.println("  PID mappings:");
9175                        printed = true;
9176                    }
9177                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9178                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9179                }
9180            }
9181        }
9182
9183        if (mForegroundProcesses.size() > 0) {
9184            synchronized (mPidsSelfLocked) {
9185                boolean printed = false;
9186                for (int i=0; i<mForegroundProcesses.size(); i++) {
9187                    ProcessRecord r = mPidsSelfLocked.get(
9188                            mForegroundProcesses.valueAt(i).pid);
9189                    if (dumpPackage != null && (r == null
9190                            || !dumpPackage.equals(r.info.packageName))) {
9191                        continue;
9192                    }
9193                    if (!printed) {
9194                        if (needSep) pw.println(" ");
9195                        needSep = true;
9196                        pw.println("  Foreground Processes:");
9197                        printed = true;
9198                    }
9199                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9200                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9201                }
9202            }
9203        }
9204
9205        if (mPersistentStartingProcesses.size() > 0) {
9206            if (needSep) pw.println(" ");
9207            needSep = true;
9208            pw.println("  Persisent processes that are starting:");
9209            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9210                    "Starting Norm", "Restarting PERS", dumpPackage);
9211        }
9212
9213        if (mRemovedProcesses.size() > 0) {
9214            if (needSep) pw.println(" ");
9215            needSep = true;
9216            pw.println("  Processes that are being removed:");
9217            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9218                    "Removed Norm", "Removed PERS", dumpPackage);
9219        }
9220
9221        if (mProcessesOnHold.size() > 0) {
9222            if (needSep) pw.println(" ");
9223            needSep = true;
9224            pw.println("  Processes that are on old until the system is ready:");
9225            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9226                    "OnHold Norm", "OnHold PERS", dumpPackage);
9227        }
9228
9229        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9230
9231        if (mProcessCrashTimes.getMap().size() > 0) {
9232            boolean printed = false;
9233            long now = SystemClock.uptimeMillis();
9234            for (Map.Entry<String, SparseArray<Long>> procs
9235                    : mProcessCrashTimes.getMap().entrySet()) {
9236                String pname = procs.getKey();
9237                SparseArray<Long> uids = procs.getValue();
9238                final int N = uids.size();
9239                for (int i=0; i<N; i++) {
9240                    int puid = uids.keyAt(i);
9241                    ProcessRecord r = mProcessNames.get(pname, puid);
9242                    if (dumpPackage != null && (r == null
9243                            || !dumpPackage.equals(r.info.packageName))) {
9244                        continue;
9245                    }
9246                    if (!printed) {
9247                        if (needSep) pw.println(" ");
9248                        needSep = true;
9249                        pw.println("  Time since processes crashed:");
9250                        printed = true;
9251                    }
9252                    pw.print("    Process "); pw.print(pname);
9253                            pw.print(" uid "); pw.print(puid);
9254                            pw.print(": last crashed ");
9255                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9256                            pw.println(" ago");
9257                }
9258            }
9259        }
9260
9261        if (mBadProcesses.getMap().size() > 0) {
9262            boolean printed = false;
9263            for (Map.Entry<String, SparseArray<Long>> procs
9264                    : mBadProcesses.getMap().entrySet()) {
9265                String pname = procs.getKey();
9266                SparseArray<Long> uids = procs.getValue();
9267                final int N = uids.size();
9268                for (int i=0; i<N; i++) {
9269                    int puid = uids.keyAt(i);
9270                    ProcessRecord r = mProcessNames.get(pname, puid);
9271                    if (dumpPackage != null && (r == null
9272                            || !dumpPackage.equals(r.info.packageName))) {
9273                        continue;
9274                    }
9275                    if (!printed) {
9276                        if (needSep) pw.println(" ");
9277                        needSep = true;
9278                        pw.println("  Bad processes:");
9279                    }
9280                    pw.print("    Bad process "); pw.print(pname);
9281                            pw.print(" uid "); pw.print(puid);
9282                            pw.print(": crashed at time ");
9283                            pw.println(uids.valueAt(i));
9284                }
9285            }
9286        }
9287
9288        pw.println();
9289        pw.println("  mStartedUsers:");
9290        for (int i=0; i<mStartedUsers.size(); i++) {
9291            UserStartedState uss = mStartedUsers.valueAt(i);
9292            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9293                    pw.print(": "); uss.dump("", pw);
9294        }
9295        pw.print("  mUserLru: [");
9296        for (int i=0; i<mUserLru.size(); i++) {
9297            if (i > 0) pw.print(", ");
9298            pw.print(mUserLru.get(i));
9299        }
9300        pw.println("]");
9301        pw.println("  mHomeProcess: " + mHomeProcess);
9302        pw.println("  mPreviousProcess: " + mPreviousProcess);
9303        if (dumpAll) {
9304            StringBuilder sb = new StringBuilder(128);
9305            sb.append("  mPreviousProcessVisibleTime: ");
9306            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9307            pw.println(sb);
9308        }
9309        if (mHeavyWeightProcess != null) {
9310            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9311        }
9312        pw.println("  mConfiguration: " + mConfiguration);
9313        if (dumpAll) {
9314            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9315            if (mCompatModePackages.getPackages().size() > 0) {
9316                boolean printed = false;
9317                for (Map.Entry<String, Integer> entry
9318                        : mCompatModePackages.getPackages().entrySet()) {
9319                    String pkg = entry.getKey();
9320                    int mode = entry.getValue();
9321                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9322                        continue;
9323                    }
9324                    if (!printed) {
9325                        pw.println("  mScreenCompatPackages:");
9326                        printed = true;
9327                    }
9328                    pw.print("    "); pw.print(pkg); pw.print(": ");
9329                            pw.print(mode); pw.println();
9330                }
9331            }
9332        }
9333        if (mSleeping || mWentToSleep || mLockScreenShown) {
9334            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9335                    + " mLockScreenShown " + mLockScreenShown);
9336        }
9337        if (mShuttingDown) {
9338            pw.println("  mShuttingDown=" + mShuttingDown);
9339        }
9340        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9341                || mOrigWaitForDebugger) {
9342            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9343                    + " mDebugTransient=" + mDebugTransient
9344                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9345        }
9346        if (mOpenGlTraceApp != null) {
9347            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9348        }
9349        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9350                || mProfileFd != null) {
9351            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9352            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9353            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9354                    + mAutoStopProfiler);
9355        }
9356        if (mAlwaysFinishActivities || mController != null) {
9357            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9358                    + " mController=" + mController);
9359        }
9360        if (dumpAll) {
9361            pw.println("  Total persistent processes: " + numPers);
9362            pw.println("  mStartRunning=" + mStartRunning
9363                    + " mProcessesReady=" + mProcessesReady
9364                    + " mSystemReady=" + mSystemReady);
9365            pw.println("  mBooting=" + mBooting
9366                    + " mBooted=" + mBooted
9367                    + " mFactoryTest=" + mFactoryTest);
9368            pw.print("  mLastPowerCheckRealtime=");
9369                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9370                    pw.println("");
9371            pw.print("  mLastPowerCheckUptime=");
9372                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9373                    pw.println("");
9374            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9375            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9376            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9377            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9378                    + " mNumHiddenProcs=" + mNumHiddenProcs
9379                    + " mNumServiceProcs=" + mNumServiceProcs
9380                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9381        }
9382
9383        return true;
9384    }
9385
9386    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9387            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9388        if (mProcessesToGc.size() > 0) {
9389            boolean printed = false;
9390            long now = SystemClock.uptimeMillis();
9391            for (int i=0; i<mProcessesToGc.size(); i++) {
9392                ProcessRecord proc = mProcessesToGc.get(i);
9393                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9394                    continue;
9395                }
9396                if (!printed) {
9397                    if (needSep) pw.println(" ");
9398                    needSep = true;
9399                    pw.println("  Processes that are waiting to GC:");
9400                    printed = true;
9401                }
9402                pw.print("    Process "); pw.println(proc);
9403                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9404                        pw.print(", last gced=");
9405                        pw.print(now-proc.lastRequestedGc);
9406                        pw.print(" ms ago, last lowMem=");
9407                        pw.print(now-proc.lastLowMemory);
9408                        pw.println(" ms ago");
9409
9410            }
9411        }
9412        return needSep;
9413    }
9414
9415    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9416            int opti, boolean dumpAll) {
9417        boolean needSep = false;
9418
9419        if (mLruProcesses.size() > 0) {
9420            if (needSep) pw.println(" ");
9421            needSep = true;
9422            pw.println("  OOM levels:");
9423            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9424            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9425            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9426            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9427            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9428            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9429            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9430            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9431            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9432            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9433            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9434            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9435            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9436
9437            if (needSep) pw.println(" ");
9438            needSep = true;
9439            pw.println("  Process OOM control:");
9440            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9441                    "Proc", "PERS", true, null);
9442            needSep = true;
9443        }
9444
9445        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9446
9447        pw.println();
9448        pw.println("  mHomeProcess: " + mHomeProcess);
9449        pw.println("  mPreviousProcess: " + mPreviousProcess);
9450        if (mHeavyWeightProcess != null) {
9451            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9452        }
9453
9454        return true;
9455    }
9456
9457    /**
9458     * There are three ways to call this:
9459     *  - no provider specified: dump all the providers
9460     *  - a flattened component name that matched an existing provider was specified as the
9461     *    first arg: dump that one provider
9462     *  - the first arg isn't the flattened component name of an existing provider:
9463     *    dump all providers whose component contains the first arg as a substring
9464     */
9465    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9466            int opti, boolean dumpAll) {
9467        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9468    }
9469
9470    static class ItemMatcher {
9471        ArrayList<ComponentName> components;
9472        ArrayList<String> strings;
9473        ArrayList<Integer> objects;
9474        boolean all;
9475
9476        ItemMatcher() {
9477            all = true;
9478        }
9479
9480        void build(String name) {
9481            ComponentName componentName = ComponentName.unflattenFromString(name);
9482            if (componentName != null) {
9483                if (components == null) {
9484                    components = new ArrayList<ComponentName>();
9485                }
9486                components.add(componentName);
9487                all = false;
9488            } else {
9489                int objectId = 0;
9490                // Not a '/' separated full component name; maybe an object ID?
9491                try {
9492                    objectId = Integer.parseInt(name, 16);
9493                    if (objects == null) {
9494                        objects = new ArrayList<Integer>();
9495                    }
9496                    objects.add(objectId);
9497                    all = false;
9498                } catch (RuntimeException e) {
9499                    // Not an integer; just do string match.
9500                    if (strings == null) {
9501                        strings = new ArrayList<String>();
9502                    }
9503                    strings.add(name);
9504                    all = false;
9505                }
9506            }
9507        }
9508
9509        int build(String[] args, int opti) {
9510            for (; opti<args.length; opti++) {
9511                String name = args[opti];
9512                if ("--".equals(name)) {
9513                    return opti+1;
9514                }
9515                build(name);
9516            }
9517            return opti;
9518        }
9519
9520        boolean match(Object object, ComponentName comp) {
9521            if (all) {
9522                return true;
9523            }
9524            if (components != null) {
9525                for (int i=0; i<components.size(); i++) {
9526                    if (components.get(i).equals(comp)) {
9527                        return true;
9528                    }
9529                }
9530            }
9531            if (objects != null) {
9532                for (int i=0; i<objects.size(); i++) {
9533                    if (System.identityHashCode(object) == objects.get(i)) {
9534                        return true;
9535                    }
9536                }
9537            }
9538            if (strings != null) {
9539                String flat = comp.flattenToString();
9540                for (int i=0; i<strings.size(); i++) {
9541                    if (flat.contains(strings.get(i))) {
9542                        return true;
9543                    }
9544                }
9545            }
9546            return false;
9547        }
9548    }
9549
9550    /**
9551     * There are three things that cmd can be:
9552     *  - a flattened component name that matches an existing activity
9553     *  - the cmd arg isn't the flattened component name of an existing activity:
9554     *    dump all activity whose component contains the cmd as a substring
9555     *  - A hex number of the ActivityRecord object instance.
9556     */
9557    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9558            int opti, boolean dumpAll) {
9559        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9560
9561        if ("all".equals(name)) {
9562            synchronized (this) {
9563                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9564                    activities.add(r1);
9565                }
9566            }
9567        } else if ("top".equals(name)) {
9568            synchronized (this) {
9569                final int N = mMainStack.mHistory.size();
9570                if (N > 0) {
9571                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9572                }
9573            }
9574        } else {
9575            ItemMatcher matcher = new ItemMatcher();
9576            matcher.build(name);
9577
9578            synchronized (this) {
9579                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9580                    if (matcher.match(r1, r1.intent.getComponent())) {
9581                        activities.add(r1);
9582                    }
9583                }
9584            }
9585        }
9586
9587        if (activities.size() <= 0) {
9588            return false;
9589        }
9590
9591        String[] newArgs = new String[args.length - opti];
9592        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9593
9594        TaskRecord lastTask = null;
9595        boolean needSep = false;
9596        for (int i=activities.size()-1; i>=0; i--) {
9597            ActivityRecord r = (ActivityRecord)activities.get(i);
9598            if (needSep) {
9599                pw.println();
9600            }
9601            needSep = true;
9602            synchronized (this) {
9603                if (lastTask != r.task) {
9604                    lastTask = r.task;
9605                    pw.print("TASK "); pw.print(lastTask.affinity);
9606                            pw.print(" id="); pw.println(lastTask.taskId);
9607                    if (dumpAll) {
9608                        lastTask.dump(pw, "  ");
9609                    }
9610                }
9611            }
9612            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9613        }
9614        return true;
9615    }
9616
9617    /**
9618     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9619     * there is a thread associated with the activity.
9620     */
9621    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9622            final ActivityRecord r, String[] args, boolean dumpAll) {
9623        String innerPrefix = prefix + "  ";
9624        synchronized (this) {
9625            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9626                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9627                    pw.print(" pid=");
9628                    if (r.app != null) pw.println(r.app.pid);
9629                    else pw.println("(not running)");
9630            if (dumpAll) {
9631                r.dump(pw, innerPrefix);
9632            }
9633        }
9634        if (r.app != null && r.app.thread != null) {
9635            // flush anything that is already in the PrintWriter since the thread is going
9636            // to write to the file descriptor directly
9637            pw.flush();
9638            try {
9639                TransferPipe tp = new TransferPipe();
9640                try {
9641                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9642                            r.appToken, innerPrefix, args);
9643                    tp.go(fd);
9644                } finally {
9645                    tp.kill();
9646                }
9647            } catch (IOException e) {
9648                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9649            } catch (RemoteException e) {
9650                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9651            }
9652        }
9653    }
9654
9655    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9656            int opti, boolean dumpAll, String dumpPackage) {
9657        boolean needSep = false;
9658        boolean onlyHistory = false;
9659
9660        if ("history".equals(dumpPackage)) {
9661            onlyHistory = true;
9662            dumpPackage = null;
9663        }
9664
9665        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9666        if (!onlyHistory && dumpAll) {
9667            if (mRegisteredReceivers.size() > 0) {
9668                boolean printed = false;
9669                Iterator it = mRegisteredReceivers.values().iterator();
9670                while (it.hasNext()) {
9671                    ReceiverList r = (ReceiverList)it.next();
9672                    if (dumpPackage != null && (r.app == null ||
9673                            !dumpPackage.equals(r.app.info.packageName))) {
9674                        continue;
9675                    }
9676                    if (!printed) {
9677                        pw.println("  Registered Receivers:");
9678                        needSep = true;
9679                        printed = true;
9680                    }
9681                    pw.print("  * "); pw.println(r);
9682                    r.dump(pw, "    ");
9683                }
9684            }
9685
9686            if (mReceiverResolver.dump(pw, needSep ?
9687                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9688                    "    ", dumpPackage, false)) {
9689                needSep = true;
9690            }
9691        }
9692
9693        for (BroadcastQueue q : mBroadcastQueues) {
9694            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9695        }
9696
9697        needSep = true;
9698
9699        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9700            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9701                if (needSep) {
9702                    pw.println();
9703                }
9704                needSep = true;
9705                pw.print("  Sticky broadcasts for user ");
9706                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9707                StringBuilder sb = new StringBuilder(128);
9708                for (Map.Entry<String, ArrayList<Intent>> ent
9709                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9710                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9711                    if (dumpAll) {
9712                        pw.println(":");
9713                        ArrayList<Intent> intents = ent.getValue();
9714                        final int N = intents.size();
9715                        for (int i=0; i<N; i++) {
9716                            sb.setLength(0);
9717                            sb.append("    Intent: ");
9718                            intents.get(i).toShortString(sb, false, true, false, false);
9719                            pw.println(sb.toString());
9720                            Bundle bundle = intents.get(i).getExtras();
9721                            if (bundle != null) {
9722                                pw.print("      ");
9723                                pw.println(bundle.toString());
9724                            }
9725                        }
9726                    } else {
9727                        pw.println("");
9728                    }
9729                }
9730            }
9731        }
9732
9733        if (!onlyHistory && dumpAll) {
9734            pw.println();
9735            for (BroadcastQueue queue : mBroadcastQueues) {
9736                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9737                        + queue.mBroadcastsScheduled);
9738            }
9739            pw.println("  mHandler:");
9740            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9741            needSep = true;
9742        }
9743
9744        return needSep;
9745    }
9746
9747    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9748            int opti, boolean dumpAll, String dumpPackage) {
9749        boolean needSep = true;
9750
9751        ItemMatcher matcher = new ItemMatcher();
9752        matcher.build(args, opti);
9753
9754        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9755
9756        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9757
9758        if (mLaunchingProviders.size() > 0) {
9759            boolean printed = false;
9760            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9761                ContentProviderRecord r = mLaunchingProviders.get(i);
9762                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9763                    continue;
9764                }
9765                if (!printed) {
9766                    if (needSep) pw.println(" ");
9767                    needSep = true;
9768                    pw.println("  Launching content providers:");
9769                    printed = true;
9770                }
9771                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9772                        pw.println(r);
9773            }
9774        }
9775
9776        if (mGrantedUriPermissions.size() > 0) {
9777            if (needSep) pw.println();
9778            needSep = true;
9779            pw.println("Granted Uri Permissions:");
9780            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9781                int uid = mGrantedUriPermissions.keyAt(i);
9782                HashMap<Uri, UriPermission> perms
9783                        = mGrantedUriPermissions.valueAt(i);
9784                pw.print("  * UID "); pw.print(uid);
9785                        pw.println(" holds:");
9786                for (UriPermission perm : perms.values()) {
9787                    pw.print("    "); pw.println(perm);
9788                    if (dumpAll) {
9789                        perm.dump(pw, "      ");
9790                    }
9791                }
9792            }
9793            needSep = true;
9794        }
9795
9796        return needSep;
9797    }
9798
9799    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9800            int opti, boolean dumpAll, String dumpPackage) {
9801        boolean needSep = false;
9802
9803        if (mIntentSenderRecords.size() > 0) {
9804            boolean printed = false;
9805            Iterator<WeakReference<PendingIntentRecord>> it
9806                    = mIntentSenderRecords.values().iterator();
9807            while (it.hasNext()) {
9808                WeakReference<PendingIntentRecord> ref = it.next();
9809                PendingIntentRecord rec = ref != null ? ref.get(): null;
9810                if (dumpPackage != null && (rec == null
9811                        || !dumpPackage.equals(rec.key.packageName))) {
9812                    continue;
9813                }
9814                if (!printed) {
9815                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9816                    printed = true;
9817                }
9818                needSep = true;
9819                if (rec != null) {
9820                    pw.print("  * "); pw.println(rec);
9821                    if (dumpAll) {
9822                        rec.dump(pw, "    ");
9823                    }
9824                } else {
9825                    pw.print("  * "); pw.println(ref);
9826                }
9827            }
9828        }
9829
9830        return needSep;
9831    }
9832
9833    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9834            String prefix, String label, boolean complete, boolean brief, boolean client,
9835            String dumpPackage) {
9836        TaskRecord lastTask = null;
9837        boolean needNL = false;
9838        final String innerPrefix = prefix + "      ";
9839        final String[] args = new String[0];
9840        for (int i=list.size()-1; i>=0; i--) {
9841            final ActivityRecord r = (ActivityRecord)list.get(i);
9842            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9843                continue;
9844            }
9845            final boolean full = !brief && (complete || !r.isInHistory());
9846            if (needNL) {
9847                pw.println(" ");
9848                needNL = false;
9849            }
9850            if (lastTask != r.task) {
9851                lastTask = r.task;
9852                pw.print(prefix);
9853                pw.print(full ? "* " : "  ");
9854                pw.println(lastTask);
9855                if (full) {
9856                    lastTask.dump(pw, prefix + "  ");
9857                } else if (complete) {
9858                    // Complete + brief == give a summary.  Isn't that obvious?!?
9859                    if (lastTask.intent != null) {
9860                        pw.print(prefix); pw.print("  ");
9861                                pw.println(lastTask.intent.toInsecureStringWithClip());
9862                    }
9863                }
9864            }
9865            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9866            pw.print(" #"); pw.print(i); pw.print(": ");
9867            pw.println(r);
9868            if (full) {
9869                r.dump(pw, innerPrefix);
9870            } else if (complete) {
9871                // Complete + brief == give a summary.  Isn't that obvious?!?
9872                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9873                if (r.app != null) {
9874                    pw.print(innerPrefix); pw.println(r.app);
9875                }
9876            }
9877            if (client && r.app != null && r.app.thread != null) {
9878                // flush anything that is already in the PrintWriter since the thread is going
9879                // to write to the file descriptor directly
9880                pw.flush();
9881                try {
9882                    TransferPipe tp = new TransferPipe();
9883                    try {
9884                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9885                                r.appToken, innerPrefix, args);
9886                        // Short timeout, since blocking here can
9887                        // deadlock with the application.
9888                        tp.go(fd, 2000);
9889                    } finally {
9890                        tp.kill();
9891                    }
9892                } catch (IOException e) {
9893                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9894                } catch (RemoteException e) {
9895                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9896                }
9897                needNL = true;
9898            }
9899        }
9900    }
9901
9902    private static String buildOomTag(String prefix, String space, int val, int base) {
9903        if (val == base) {
9904            if (space == null) return prefix;
9905            return prefix + "  ";
9906        }
9907        return prefix + "+" + Integer.toString(val-base);
9908    }
9909
9910    private static final int dumpProcessList(PrintWriter pw,
9911            ActivityManagerService service, List list,
9912            String prefix, String normalLabel, String persistentLabel,
9913            String dumpPackage) {
9914        int numPers = 0;
9915        final int N = list.size()-1;
9916        for (int i=N; i>=0; i--) {
9917            ProcessRecord r = (ProcessRecord)list.get(i);
9918            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9919                continue;
9920            }
9921            pw.println(String.format("%s%s #%2d: %s",
9922                    prefix, (r.persistent ? persistentLabel : normalLabel),
9923                    i, r.toString()));
9924            if (r.persistent) {
9925                numPers++;
9926            }
9927        }
9928        return numPers;
9929    }
9930
9931    private static final boolean dumpProcessOomList(PrintWriter pw,
9932            ActivityManagerService service, List<ProcessRecord> origList,
9933            String prefix, String normalLabel, String persistentLabel,
9934            boolean inclDetails, String dumpPackage) {
9935
9936        ArrayList<Pair<ProcessRecord, Integer>> list
9937                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9938        for (int i=0; i<origList.size(); i++) {
9939            ProcessRecord r = origList.get(i);
9940            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9941                continue;
9942            }
9943            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9944        }
9945
9946        if (list.size() <= 0) {
9947            return false;
9948        }
9949
9950        Comparator<Pair<ProcessRecord, Integer>> comparator
9951                = new Comparator<Pair<ProcessRecord, Integer>>() {
9952            @Override
9953            public int compare(Pair<ProcessRecord, Integer> object1,
9954                    Pair<ProcessRecord, Integer> object2) {
9955                if (object1.first.setAdj != object2.first.setAdj) {
9956                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9957                }
9958                if (object1.second.intValue() != object2.second.intValue()) {
9959                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9960                }
9961                return 0;
9962            }
9963        };
9964
9965        Collections.sort(list, comparator);
9966
9967        final long curRealtime = SystemClock.elapsedRealtime();
9968        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9969        final long curUptime = SystemClock.uptimeMillis();
9970        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9971
9972        for (int i=list.size()-1; i>=0; i--) {
9973            ProcessRecord r = list.get(i).first;
9974            String oomAdj;
9975            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9976                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9977            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9978                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9979            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9980                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9981            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9982                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9983            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9984                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9985            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9986                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9987            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9988                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9989            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9990                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9991            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9992                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9993            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9994                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9995            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9996                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9997            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9998                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9999            } else {
10000                oomAdj = Integer.toString(r.setAdj);
10001            }
10002            String schedGroup;
10003            switch (r.setSchedGroup) {
10004                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10005                    schedGroup = "B";
10006                    break;
10007                case Process.THREAD_GROUP_DEFAULT:
10008                    schedGroup = "F";
10009                    break;
10010                default:
10011                    schedGroup = Integer.toString(r.setSchedGroup);
10012                    break;
10013            }
10014            String foreground;
10015            if (r.foregroundActivities) {
10016                foreground = "A";
10017            } else if (r.foregroundServices) {
10018                foreground = "S";
10019            } else {
10020                foreground = " ";
10021            }
10022            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10023                    prefix, (r.persistent ? persistentLabel : normalLabel),
10024                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10025                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10026            if (r.adjSource != null || r.adjTarget != null) {
10027                pw.print(prefix);
10028                pw.print("    ");
10029                if (r.adjTarget instanceof ComponentName) {
10030                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10031                } else if (r.adjTarget != null) {
10032                    pw.print(r.adjTarget.toString());
10033                } else {
10034                    pw.print("{null}");
10035                }
10036                pw.print("<=");
10037                if (r.adjSource instanceof ProcessRecord) {
10038                    pw.print("Proc{");
10039                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10040                    pw.println("}");
10041                } else if (r.adjSource != null) {
10042                    pw.println(r.adjSource.toString());
10043                } else {
10044                    pw.println("{null}");
10045                }
10046            }
10047            if (inclDetails) {
10048                pw.print(prefix);
10049                pw.print("    ");
10050                pw.print("oom: max="); pw.print(r.maxAdj);
10051                pw.print(" hidden="); pw.print(r.hiddenAdj);
10052                pw.print(" empty="); pw.print(r.emptyAdj);
10053                pw.print(" curRaw="); pw.print(r.curRawAdj);
10054                pw.print(" setRaw="); pw.print(r.setRawAdj);
10055                pw.print(" cur="); pw.print(r.curAdj);
10056                pw.print(" set="); pw.println(r.setAdj);
10057                pw.print(prefix);
10058                pw.print("    ");
10059                pw.print("keeping="); pw.print(r.keeping);
10060                pw.print(" hidden="); pw.print(r.hidden);
10061                pw.print(" empty="); pw.print(r.empty);
10062                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10063
10064                if (!r.keeping) {
10065                    if (r.lastWakeTime != 0) {
10066                        long wtime;
10067                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10068                        synchronized (stats) {
10069                            wtime = stats.getProcessWakeTime(r.info.uid,
10070                                    r.pid, curRealtime);
10071                        }
10072                        long timeUsed = wtime - r.lastWakeTime;
10073                        pw.print(prefix);
10074                        pw.print("    ");
10075                        pw.print("keep awake over ");
10076                        TimeUtils.formatDuration(realtimeSince, pw);
10077                        pw.print(" used ");
10078                        TimeUtils.formatDuration(timeUsed, pw);
10079                        pw.print(" (");
10080                        pw.print((timeUsed*100)/realtimeSince);
10081                        pw.println("%)");
10082                    }
10083                    if (r.lastCpuTime != 0) {
10084                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10085                        pw.print(prefix);
10086                        pw.print("    ");
10087                        pw.print("run cpu over ");
10088                        TimeUtils.formatDuration(uptimeSince, pw);
10089                        pw.print(" used ");
10090                        TimeUtils.formatDuration(timeUsed, pw);
10091                        pw.print(" (");
10092                        pw.print((timeUsed*100)/uptimeSince);
10093                        pw.println("%)");
10094                    }
10095                }
10096            }
10097        }
10098        return true;
10099    }
10100
10101    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10102        ArrayList<ProcessRecord> procs;
10103        synchronized (this) {
10104            if (args != null && args.length > start
10105                    && args[start].charAt(0) != '-') {
10106                procs = new ArrayList<ProcessRecord>();
10107                int pid = -1;
10108                try {
10109                    pid = Integer.parseInt(args[start]);
10110                } catch (NumberFormatException e) {
10111
10112                }
10113                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10114                    ProcessRecord proc = mLruProcesses.get(i);
10115                    if (proc.pid == pid) {
10116                        procs.add(proc);
10117                    } else if (proc.processName.equals(args[start])) {
10118                        procs.add(proc);
10119                    }
10120                }
10121                if (procs.size() <= 0) {
10122                    pw.println("No process found for: " + args[start]);
10123                    return null;
10124                }
10125            } else {
10126                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10127            }
10128        }
10129        return procs;
10130    }
10131
10132    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10133            PrintWriter pw, String[] args) {
10134        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10135        if (procs == null) {
10136            return;
10137        }
10138
10139        long uptime = SystemClock.uptimeMillis();
10140        long realtime = SystemClock.elapsedRealtime();
10141        pw.println("Applications Graphics Acceleration Info:");
10142        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10143
10144        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10145            ProcessRecord r = procs.get(i);
10146            if (r.thread != null) {
10147                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10148                pw.flush();
10149                try {
10150                    TransferPipe tp = new TransferPipe();
10151                    try {
10152                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10153                        tp.go(fd);
10154                    } finally {
10155                        tp.kill();
10156                    }
10157                } catch (IOException e) {
10158                    pw.println("Failure while dumping the app: " + r);
10159                    pw.flush();
10160                } catch (RemoteException e) {
10161                    pw.println("Got a RemoteException while dumping the app " + r);
10162                    pw.flush();
10163                }
10164            }
10165        }
10166    }
10167
10168    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10169        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10170        if (procs == null) {
10171            return;
10172        }
10173
10174        pw.println("Applications Database Info:");
10175
10176        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10177            ProcessRecord r = procs.get(i);
10178            if (r.thread != null) {
10179                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10180                pw.flush();
10181                try {
10182                    TransferPipe tp = new TransferPipe();
10183                    try {
10184                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10185                        tp.go(fd);
10186                    } finally {
10187                        tp.kill();
10188                    }
10189                } catch (IOException e) {
10190                    pw.println("Failure while dumping the app: " + r);
10191                    pw.flush();
10192                } catch (RemoteException e) {
10193                    pw.println("Got a RemoteException while dumping the app " + r);
10194                    pw.flush();
10195                }
10196            }
10197        }
10198    }
10199
10200    final static class MemItem {
10201        final String label;
10202        final String shortLabel;
10203        final long pss;
10204        final int id;
10205        ArrayList<MemItem> subitems;
10206
10207        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10208            label = _label;
10209            shortLabel = _shortLabel;
10210            pss = _pss;
10211            id = _id;
10212        }
10213    }
10214
10215    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10216            boolean sort) {
10217        if (sort) {
10218            Collections.sort(items, new Comparator<MemItem>() {
10219                @Override
10220                public int compare(MemItem lhs, MemItem rhs) {
10221                    if (lhs.pss < rhs.pss) {
10222                        return 1;
10223                    } else if (lhs.pss > rhs.pss) {
10224                        return -1;
10225                    }
10226                    return 0;
10227                }
10228            });
10229        }
10230
10231        for (int i=0; i<items.size(); i++) {
10232            MemItem mi = items.get(i);
10233            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10234            if (mi.subitems != null) {
10235                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10236            }
10237        }
10238    }
10239
10240    // These are in KB.
10241    static final long[] DUMP_MEM_BUCKETS = new long[] {
10242        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10243        120*1024, 160*1024, 200*1024,
10244        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10245        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10246    };
10247
10248    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10249            boolean stackLike) {
10250        int start = label.lastIndexOf('.');
10251        if (start >= 0) start++;
10252        else start = 0;
10253        int end = label.length();
10254        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10255            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10256                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10257                out.append(bucket);
10258                out.append(stackLike ? "MB." : "MB ");
10259                out.append(label, start, end);
10260                return;
10261            }
10262        }
10263        out.append(memKB/1024);
10264        out.append(stackLike ? "MB." : "MB ");
10265        out.append(label, start, end);
10266    }
10267
10268    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10269            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10270            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10271            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10272            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10273    };
10274    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10275            "System", "Persistent", "Foreground",
10276            "Visible", "Perceptible", "Heavy Weight",
10277            "Backup", "A Services", "Home", "Previous",
10278            "B Services", "Background"
10279    };
10280
10281    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10282            PrintWriter pw, String prefix, String[] args, boolean brief,
10283            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10284        boolean dumpAll = false;
10285        boolean oomOnly = false;
10286
10287        int opti = 0;
10288        while (opti < args.length) {
10289            String opt = args[opti];
10290            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10291                break;
10292            }
10293            opti++;
10294            if ("-a".equals(opt)) {
10295                dumpAll = true;
10296            } else if ("--oom".equals(opt)) {
10297                oomOnly = true;
10298            } else if ("-h".equals(opt)) {
10299                pw.println("meminfo dump options: [-a] [--oom] [process]");
10300                pw.println("  -a: include all available information for each process.");
10301                pw.println("  --oom: only show processes organized by oom adj.");
10302                pw.println("If [process] is specified it can be the name or ");
10303                pw.println("pid of a specific process to dump.");
10304                return;
10305            } else {
10306                pw.println("Unknown argument: " + opt + "; use -h for help");
10307            }
10308        }
10309
10310        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10311        if (procs == null) {
10312            return;
10313        }
10314
10315        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10316        long uptime = SystemClock.uptimeMillis();
10317        long realtime = SystemClock.elapsedRealtime();
10318
10319        if (procs.size() == 1 || isCheckinRequest) {
10320            dumpAll = true;
10321        }
10322
10323        if (isCheckinRequest) {
10324            // short checkin version
10325            pw.println(uptime + "," + realtime);
10326            pw.flush();
10327        } else {
10328            pw.println("Applications Memory Usage (kB):");
10329            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10330        }
10331
10332        String[] innerArgs = new String[args.length-opti];
10333        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10334
10335        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10336        long nativePss=0, dalvikPss=0, otherPss=0;
10337        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10338
10339        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10340        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10341                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10342
10343        long totalPss = 0;
10344
10345        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10346            ProcessRecord r = procs.get(i);
10347            if (r.thread != null) {
10348                if (!isCheckinRequest && dumpAll) {
10349                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10350                    pw.flush();
10351                }
10352                Debug.MemoryInfo mi = null;
10353                if (dumpAll) {
10354                    try {
10355                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10356                    } catch (RemoteException e) {
10357                        if (!isCheckinRequest) {
10358                            pw.println("Got RemoteException!");
10359                            pw.flush();
10360                        }
10361                    }
10362                } else {
10363                    mi = new Debug.MemoryInfo();
10364                    Debug.getMemoryInfo(r.pid, mi);
10365                }
10366
10367                if (!isCheckinRequest && mi != null) {
10368                    long myTotalPss = mi.getTotalPss();
10369                    totalPss += myTotalPss;
10370                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10371                            r.processName, myTotalPss, 0);
10372                    procMems.add(pssItem);
10373
10374                    nativePss += mi.nativePss;
10375                    dalvikPss += mi.dalvikPss;
10376                    otherPss += mi.otherPss;
10377                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10378                        long mem = mi.getOtherPss(j);
10379                        miscPss[j] += mem;
10380                        otherPss -= mem;
10381                    }
10382
10383                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10384                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10385                                || oomIndex == (oomPss.length-1)) {
10386                            oomPss[oomIndex] += myTotalPss;
10387                            if (oomProcs[oomIndex] == null) {
10388                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10389                            }
10390                            oomProcs[oomIndex].add(pssItem);
10391                            break;
10392                        }
10393                    }
10394                }
10395            }
10396        }
10397
10398        if (!isCheckinRequest && procs.size() > 1) {
10399            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10400
10401            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10402            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10403            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10404            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10405                String label = Debug.MemoryInfo.getOtherLabel(j);
10406                catMems.add(new MemItem(label, label, miscPss[j], j));
10407            }
10408
10409            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10410            for (int j=0; j<oomPss.length; j++) {
10411                if (oomPss[j] != 0) {
10412                    String label = DUMP_MEM_OOM_LABEL[j];
10413                    MemItem item = new MemItem(label, label, oomPss[j],
10414                            DUMP_MEM_OOM_ADJ[j]);
10415                    item.subitems = oomProcs[j];
10416                    oomMems.add(item);
10417                }
10418            }
10419
10420            if (outTag != null || outStack != null) {
10421                if (outTag != null) {
10422                    appendMemBucket(outTag, totalPss, "total", false);
10423                }
10424                if (outStack != null) {
10425                    appendMemBucket(outStack, totalPss, "total", true);
10426                }
10427                boolean firstLine = true;
10428                for (int i=0; i<oomMems.size(); i++) {
10429                    MemItem miCat = oomMems.get(i);
10430                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10431                        continue;
10432                    }
10433                    if (miCat.id < ProcessList.SERVICE_ADJ
10434                            || miCat.id == ProcessList.HOME_APP_ADJ
10435                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10436                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10437                            outTag.append(" / ");
10438                        }
10439                        if (outStack != null) {
10440                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10441                                if (firstLine) {
10442                                    outStack.append(":");
10443                                    firstLine = false;
10444                                }
10445                                outStack.append("\n\t at ");
10446                            } else {
10447                                outStack.append("$");
10448                            }
10449                        }
10450                        for (int j=0; j<miCat.subitems.size(); j++) {
10451                            MemItem mi = miCat.subitems.get(j);
10452                            if (j > 0) {
10453                                if (outTag != null) {
10454                                    outTag.append(" ");
10455                                }
10456                                if (outStack != null) {
10457                                    outStack.append("$");
10458                                }
10459                            }
10460                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10461                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10462                            }
10463                            if (outStack != null) {
10464                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10465                            }
10466                        }
10467                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10468                            outStack.append("(");
10469                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10470                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10471                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10472                                    outStack.append(":");
10473                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10474                                }
10475                            }
10476                            outStack.append(")");
10477                        }
10478                    }
10479                }
10480            }
10481
10482            if (!brief && !oomOnly) {
10483                pw.println();
10484                pw.println("Total PSS by process:");
10485                dumpMemItems(pw, "  ", procMems, true);
10486                pw.println();
10487            }
10488            pw.println("Total PSS by OOM adjustment:");
10489            dumpMemItems(pw, "  ", oomMems, false);
10490            if (!oomOnly) {
10491                PrintWriter out = categoryPw != null ? categoryPw : pw;
10492                out.println();
10493                out.println("Total PSS by category:");
10494                dumpMemItems(out, "  ", catMems, true);
10495            }
10496            pw.println();
10497            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10498            final int[] SINGLE_LONG_FORMAT = new int[] {
10499                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10500            };
10501            long[] longOut = new long[1];
10502            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10503                    SINGLE_LONG_FORMAT, null, longOut, null);
10504            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10505            longOut[0] = 0;
10506            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10507                    SINGLE_LONG_FORMAT, null, longOut, null);
10508            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10509            longOut[0] = 0;
10510            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10511                    SINGLE_LONG_FORMAT, null, longOut, null);
10512            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10513            longOut[0] = 0;
10514            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10515                    SINGLE_LONG_FORMAT, null, longOut, null);
10516            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10517            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10518                    pw.print(shared); pw.println(" kB");
10519            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10520                    pw.print(voltile); pw.println(" kB volatile");
10521        }
10522    }
10523
10524    /**
10525     * Searches array of arguments for the specified string
10526     * @param args array of argument strings
10527     * @param value value to search for
10528     * @return true if the value is contained in the array
10529     */
10530    private static boolean scanArgs(String[] args, String value) {
10531        if (args != null) {
10532            for (String arg : args) {
10533                if (value.equals(arg)) {
10534                    return true;
10535                }
10536            }
10537        }
10538        return false;
10539    }
10540
10541    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10542            ContentProviderRecord cpr, boolean always) {
10543        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10544
10545        if (!inLaunching || always) {
10546            synchronized (cpr) {
10547                cpr.launchingApp = null;
10548                cpr.notifyAll();
10549            }
10550            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10551            String names[] = cpr.info.authority.split(";");
10552            for (int j = 0; j < names.length; j++) {
10553                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10554            }
10555        }
10556
10557        for (int i=0; i<cpr.connections.size(); i++) {
10558            ContentProviderConnection conn = cpr.connections.get(i);
10559            if (conn.waiting) {
10560                // If this connection is waiting for the provider, then we don't
10561                // need to mess with its process unless we are always removing
10562                // or for some reason the provider is not currently launching.
10563                if (inLaunching && !always) {
10564                    continue;
10565                }
10566            }
10567            ProcessRecord capp = conn.client;
10568            conn.dead = true;
10569            if (conn.stableCount > 0) {
10570                if (!capp.persistent && capp.thread != null
10571                        && capp.pid != 0
10572                        && capp.pid != MY_PID) {
10573                    Slog.i(TAG, "Kill " + capp.processName
10574                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10575                            + " in dying process " + (proc != null ? proc.processName : "??"));
10576                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10577                            capp.processName, capp.setAdj, "dying provider "
10578                                    + cpr.name.toShortString());
10579                    Process.killProcessQuiet(capp.pid);
10580                }
10581            } else if (capp.thread != null && conn.provider.provider != null) {
10582                try {
10583                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10584                } catch (RemoteException e) {
10585                }
10586                // In the protocol here, we don't expect the client to correctly
10587                // clean up this connection, we'll just remove it.
10588                cpr.connections.remove(i);
10589                conn.client.conProviders.remove(conn);
10590            }
10591        }
10592
10593        if (inLaunching && always) {
10594            mLaunchingProviders.remove(cpr);
10595        }
10596        return inLaunching;
10597    }
10598
10599    /**
10600     * Main code for cleaning up a process when it has gone away.  This is
10601     * called both as a result of the process dying, or directly when stopping
10602     * a process when running in single process mode.
10603     */
10604    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10605            boolean restarting, boolean allowRestart, int index) {
10606        if (index >= 0) {
10607            mLruProcesses.remove(index);
10608        }
10609
10610        mProcessesToGc.remove(app);
10611
10612        // Dismiss any open dialogs.
10613        if (app.crashDialog != null) {
10614            app.crashDialog.dismiss();
10615            app.crashDialog = null;
10616        }
10617        if (app.anrDialog != null) {
10618            app.anrDialog.dismiss();
10619            app.anrDialog = null;
10620        }
10621        if (app.waitDialog != null) {
10622            app.waitDialog.dismiss();
10623            app.waitDialog = null;
10624        }
10625
10626        app.crashing = false;
10627        app.notResponding = false;
10628
10629        app.resetPackageList();
10630        app.unlinkDeathRecipient();
10631        app.thread = null;
10632        app.forcingToForeground = null;
10633        app.foregroundServices = false;
10634        app.foregroundActivities = false;
10635        app.hasShownUi = false;
10636        app.hasAboveClient = false;
10637
10638        mServices.killServicesLocked(app, allowRestart);
10639
10640        boolean restart = false;
10641
10642        // Remove published content providers.
10643        if (!app.pubProviders.isEmpty()) {
10644            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10645            while (it.hasNext()) {
10646                ContentProviderRecord cpr = it.next();
10647
10648                final boolean always = app.bad || !allowRestart;
10649                if (removeDyingProviderLocked(app, cpr, always) || always) {
10650                    // We left the provider in the launching list, need to
10651                    // restart it.
10652                    restart = true;
10653                }
10654
10655                cpr.provider = null;
10656                cpr.proc = null;
10657            }
10658            app.pubProviders.clear();
10659        }
10660
10661        // Take care of any launching providers waiting for this process.
10662        if (checkAppInLaunchingProvidersLocked(app, false)) {
10663            restart = true;
10664        }
10665
10666        // Unregister from connected content providers.
10667        if (!app.conProviders.isEmpty()) {
10668            for (int i=0; i<app.conProviders.size(); i++) {
10669                ContentProviderConnection conn = app.conProviders.get(i);
10670                conn.provider.connections.remove(conn);
10671            }
10672            app.conProviders.clear();
10673        }
10674
10675        // At this point there may be remaining entries in mLaunchingProviders
10676        // where we were the only one waiting, so they are no longer of use.
10677        // Look for these and clean up if found.
10678        // XXX Commented out for now.  Trying to figure out a way to reproduce
10679        // the actual situation to identify what is actually going on.
10680        if (false) {
10681            for (int i=0; i<mLaunchingProviders.size(); i++) {
10682                ContentProviderRecord cpr = (ContentProviderRecord)
10683                        mLaunchingProviders.get(i);
10684                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10685                    synchronized (cpr) {
10686                        cpr.launchingApp = null;
10687                        cpr.notifyAll();
10688                    }
10689                }
10690            }
10691        }
10692
10693        skipCurrentReceiverLocked(app);
10694
10695        // Unregister any receivers.
10696        if (app.receivers.size() > 0) {
10697            Iterator<ReceiverList> it = app.receivers.iterator();
10698            while (it.hasNext()) {
10699                removeReceiverLocked(it.next());
10700            }
10701            app.receivers.clear();
10702        }
10703
10704        // If the app is undergoing backup, tell the backup manager about it
10705        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10706            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10707            try {
10708                IBackupManager bm = IBackupManager.Stub.asInterface(
10709                        ServiceManager.getService(Context.BACKUP_SERVICE));
10710                bm.agentDisconnected(app.info.packageName);
10711            } catch (RemoteException e) {
10712                // can't happen; backup manager is local
10713            }
10714        }
10715
10716        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10717            ProcessChangeItem item = mPendingProcessChanges.get(i);
10718            if (item.pid == app.pid) {
10719                mPendingProcessChanges.remove(i);
10720                mAvailProcessChanges.add(item);
10721            }
10722        }
10723        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10724
10725        // If the caller is restarting this app, then leave it in its
10726        // current lists and let the caller take care of it.
10727        if (restarting) {
10728            return;
10729        }
10730
10731        if (!app.persistent || app.isolated) {
10732            if (DEBUG_PROCESSES) Slog.v(TAG,
10733                    "Removing non-persistent process during cleanup: " + app);
10734            mProcessNames.remove(app.processName, app.uid);
10735            mIsolatedProcesses.remove(app.uid);
10736            if (mHeavyWeightProcess == app) {
10737                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10738                        mHeavyWeightProcess.userId, 0));
10739                mHeavyWeightProcess = null;
10740            }
10741        } else if (!app.removed) {
10742            // This app is persistent, so we need to keep its record around.
10743            // If it is not already on the pending app list, add it there
10744            // and start a new process for it.
10745            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10746                mPersistentStartingProcesses.add(app);
10747                restart = true;
10748            }
10749        }
10750        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10751                "Clean-up removing on hold: " + app);
10752        mProcessesOnHold.remove(app);
10753
10754        if (app == mHomeProcess) {
10755            mHomeProcess = null;
10756        }
10757        if (app == mPreviousProcess) {
10758            mPreviousProcess = null;
10759        }
10760
10761        if (restart && !app.isolated) {
10762            // We have components that still need to be running in the
10763            // process, so re-launch it.
10764            mProcessNames.put(app.processName, app.uid, app);
10765            startProcessLocked(app, "restart", app.processName);
10766        } else if (app.pid > 0 && app.pid != MY_PID) {
10767            // Goodbye!
10768            synchronized (mPidsSelfLocked) {
10769                mPidsSelfLocked.remove(app.pid);
10770                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10771            }
10772            app.setPid(0);
10773        }
10774    }
10775
10776    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10777        // Look through the content providers we are waiting to have launched,
10778        // and if any run in this process then either schedule a restart of
10779        // the process or kill the client waiting for it if this process has
10780        // gone bad.
10781        int NL = mLaunchingProviders.size();
10782        boolean restart = false;
10783        for (int i=0; i<NL; i++) {
10784            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10785            if (cpr.launchingApp == app) {
10786                if (!alwaysBad && !app.bad) {
10787                    restart = true;
10788                } else {
10789                    removeDyingProviderLocked(app, cpr, true);
10790                    // cpr should have been removed from mLaunchingProviders
10791                    NL = mLaunchingProviders.size();
10792                    i--;
10793                }
10794            }
10795        }
10796        return restart;
10797    }
10798
10799    // =========================================================
10800    // SERVICES
10801    // =========================================================
10802
10803    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10804            int flags) {
10805        enforceNotIsolatedCaller("getServices");
10806        synchronized (this) {
10807            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10808        }
10809    }
10810
10811    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10812        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10813        synchronized (this) {
10814            return mServices.getRunningServiceControlPanelLocked(name);
10815        }
10816    }
10817
10818    public ComponentName startService(IApplicationThread caller, Intent service,
10819            String resolvedType, int userId) {
10820        enforceNotIsolatedCaller("startService");
10821        // Refuse possible leaked file descriptors
10822        if (service != null && service.hasFileDescriptors() == true) {
10823            throw new IllegalArgumentException("File descriptors passed in Intent");
10824        }
10825
10826        if (DEBUG_SERVICE)
10827            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10828        synchronized(this) {
10829            final int callingPid = Binder.getCallingPid();
10830            final int callingUid = Binder.getCallingUid();
10831            checkValidCaller(callingUid, userId);
10832            final long origId = Binder.clearCallingIdentity();
10833            ComponentName res = mServices.startServiceLocked(caller, service,
10834                    resolvedType, callingPid, callingUid, userId);
10835            Binder.restoreCallingIdentity(origId);
10836            return res;
10837        }
10838    }
10839
10840    ComponentName startServiceInPackage(int uid,
10841            Intent service, String resolvedType, int userId) {
10842        synchronized(this) {
10843            if (DEBUG_SERVICE)
10844                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10845            final long origId = Binder.clearCallingIdentity();
10846            ComponentName res = mServices.startServiceLocked(null, service,
10847                    resolvedType, -1, uid, userId);
10848            Binder.restoreCallingIdentity(origId);
10849            return res;
10850        }
10851    }
10852
10853    public int stopService(IApplicationThread caller, Intent service,
10854            String resolvedType, int userId) {
10855        enforceNotIsolatedCaller("stopService");
10856        // Refuse possible leaked file descriptors
10857        if (service != null && service.hasFileDescriptors() == true) {
10858            throw new IllegalArgumentException("File descriptors passed in Intent");
10859        }
10860
10861        checkValidCaller(Binder.getCallingUid(), userId);
10862
10863        synchronized(this) {
10864            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10865        }
10866    }
10867
10868    public IBinder peekService(Intent service, String resolvedType) {
10869        enforceNotIsolatedCaller("peekService");
10870        // Refuse possible leaked file descriptors
10871        if (service != null && service.hasFileDescriptors() == true) {
10872            throw new IllegalArgumentException("File descriptors passed in Intent");
10873        }
10874        synchronized(this) {
10875            return mServices.peekServiceLocked(service, resolvedType);
10876        }
10877    }
10878
10879    public boolean stopServiceToken(ComponentName className, IBinder token,
10880            int startId) {
10881        synchronized(this) {
10882            return mServices.stopServiceTokenLocked(className, token, startId);
10883        }
10884    }
10885
10886    public void setServiceForeground(ComponentName className, IBinder token,
10887            int id, Notification notification, boolean removeNotification) {
10888        synchronized(this) {
10889            mServices.setServiceForegroundLocked(className, token, id, notification,
10890                    removeNotification);
10891        }
10892    }
10893
10894    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10895            boolean requireFull, String name, String callerPackage) {
10896        synchronized(this) {
10897            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10898                    requireFull, name, callerPackage);
10899        }
10900    }
10901
10902    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10903            boolean requireFull, String name, String callerPackage) {
10904        final int callingUserId = UserHandle.getUserId(callingUid);
10905        if (callingUserId != userId) {
10906            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10907                if ((requireFull || checkComponentPermission(
10908                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10909                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10910                        && checkComponentPermission(
10911                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10912                                callingPid, callingUid, -1, true)
10913                                != PackageManager.PERMISSION_GRANTED) {
10914                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10915                        // In this case, they would like to just execute as their
10916                        // owner user instead of failing.
10917                        userId = callingUserId;
10918                    } else {
10919                        StringBuilder builder = new StringBuilder(128);
10920                        builder.append("Permission Denial: ");
10921                        builder.append(name);
10922                        if (callerPackage != null) {
10923                            builder.append(" from ");
10924                            builder.append(callerPackage);
10925                        }
10926                        builder.append(" asks to run as user ");
10927                        builder.append(userId);
10928                        builder.append(" but is calling from user ");
10929                        builder.append(UserHandle.getUserId(callingUid));
10930                        builder.append("; this requires ");
10931                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10932                        if (!requireFull) {
10933                            builder.append(" or ");
10934                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10935                        }
10936                        String msg = builder.toString();
10937                        Slog.w(TAG, msg);
10938                        throw new SecurityException(msg);
10939                    }
10940                }
10941            }
10942            if (userId == UserHandle.USER_CURRENT
10943                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10944                userId = mCurrentUserId;
10945            }
10946            if (!allowAll && userId < 0) {
10947                throw new IllegalArgumentException(
10948                        "Call does not support special user #" + userId);
10949            }
10950        }
10951        return userId;
10952    }
10953
10954    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10955            String className, int flags) {
10956        boolean result = false;
10957        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10958            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10959                if (ActivityManager.checkUidPermission(
10960                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10961                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10962                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10963                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10964                            + " requests FLAG_SINGLE_USER, but app does not hold "
10965                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10966                    Slog.w(TAG, msg);
10967                    throw new SecurityException(msg);
10968                }
10969                result = true;
10970            }
10971        } else if (componentProcessName == aInfo.packageName) {
10972            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10973        } else if ("system".equals(componentProcessName)) {
10974            result = true;
10975        }
10976        if (DEBUG_MU) {
10977            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10978                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10979        }
10980        return result;
10981    }
10982
10983    public int bindService(IApplicationThread caller, IBinder token,
10984            Intent service, String resolvedType,
10985            IServiceConnection connection, int flags, int userId) {
10986        enforceNotIsolatedCaller("bindService");
10987        // Refuse possible leaked file descriptors
10988        if (service != null && service.hasFileDescriptors() == true) {
10989            throw new IllegalArgumentException("File descriptors passed in Intent");
10990        }
10991
10992        synchronized(this) {
10993            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10994                    connection, flags, userId);
10995        }
10996    }
10997
10998    public boolean unbindService(IServiceConnection connection) {
10999        synchronized (this) {
11000            return mServices.unbindServiceLocked(connection);
11001        }
11002    }
11003
11004    public void publishService(IBinder token, Intent intent, IBinder service) {
11005        // Refuse possible leaked file descriptors
11006        if (intent != null && intent.hasFileDescriptors() == true) {
11007            throw new IllegalArgumentException("File descriptors passed in Intent");
11008        }
11009
11010        synchronized(this) {
11011            if (!(token instanceof ServiceRecord)) {
11012                throw new IllegalArgumentException("Invalid service token");
11013            }
11014            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11015        }
11016    }
11017
11018    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11019        // Refuse possible leaked file descriptors
11020        if (intent != null && intent.hasFileDescriptors() == true) {
11021            throw new IllegalArgumentException("File descriptors passed in Intent");
11022        }
11023
11024        synchronized(this) {
11025            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11026        }
11027    }
11028
11029    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11030        synchronized(this) {
11031            if (!(token instanceof ServiceRecord)) {
11032                throw new IllegalArgumentException("Invalid service token");
11033            }
11034            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11035        }
11036    }
11037
11038    // =========================================================
11039    // BACKUP AND RESTORE
11040    // =========================================================
11041
11042    // Cause the target app to be launched if necessary and its backup agent
11043    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11044    // activity manager to announce its creation.
11045    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11046        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11047        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11048
11049        synchronized(this) {
11050            // !!! TODO: currently no check here that we're already bound
11051            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11052            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11053            synchronized (stats) {
11054                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11055            }
11056
11057            // Backup agent is now in use, its package can't be stopped.
11058            try {
11059                AppGlobals.getPackageManager().setPackageStoppedState(
11060                        app.packageName, false, UserHandle.getUserId(app.uid));
11061            } catch (RemoteException e) {
11062            } catch (IllegalArgumentException e) {
11063                Slog.w(TAG, "Failed trying to unstop package "
11064                        + app.packageName + ": " + e);
11065            }
11066
11067            BackupRecord r = new BackupRecord(ss, app, backupMode);
11068            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11069                    ? new ComponentName(app.packageName, app.backupAgentName)
11070                    : new ComponentName("android", "FullBackupAgent");
11071            // startProcessLocked() returns existing proc's record if it's already running
11072            ProcessRecord proc = startProcessLocked(app.processName, app,
11073                    false, 0, "backup", hostingName, false, false);
11074            if (proc == null) {
11075                Slog.e(TAG, "Unable to start backup agent process " + r);
11076                return false;
11077            }
11078
11079            r.app = proc;
11080            mBackupTarget = r;
11081            mBackupAppName = app.packageName;
11082
11083            // Try not to kill the process during backup
11084            updateOomAdjLocked(proc);
11085
11086            // If the process is already attached, schedule the creation of the backup agent now.
11087            // If it is not yet live, this will be done when it attaches to the framework.
11088            if (proc.thread != null) {
11089                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11090                try {
11091                    proc.thread.scheduleCreateBackupAgent(app,
11092                            compatibilityInfoForPackageLocked(app), backupMode);
11093                } catch (RemoteException e) {
11094                    // Will time out on the backup manager side
11095                }
11096            } else {
11097                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11098            }
11099            // Invariants: at this point, the target app process exists and the application
11100            // is either already running or in the process of coming up.  mBackupTarget and
11101            // mBackupAppName describe the app, so that when it binds back to the AM we
11102            // know that it's scheduled for a backup-agent operation.
11103        }
11104
11105        return true;
11106    }
11107
11108    // A backup agent has just come up
11109    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11110        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11111                + " = " + agent);
11112
11113        synchronized(this) {
11114            if (!agentPackageName.equals(mBackupAppName)) {
11115                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11116                return;
11117            }
11118        }
11119
11120        long oldIdent = Binder.clearCallingIdentity();
11121        try {
11122            IBackupManager bm = IBackupManager.Stub.asInterface(
11123                    ServiceManager.getService(Context.BACKUP_SERVICE));
11124            bm.agentConnected(agentPackageName, agent);
11125        } catch (RemoteException e) {
11126            // can't happen; the backup manager service is local
11127        } catch (Exception e) {
11128            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11129            e.printStackTrace();
11130        } finally {
11131            Binder.restoreCallingIdentity(oldIdent);
11132        }
11133    }
11134
11135    // done with this agent
11136    public void unbindBackupAgent(ApplicationInfo appInfo) {
11137        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11138        if (appInfo == null) {
11139            Slog.w(TAG, "unbind backup agent for null app");
11140            return;
11141        }
11142
11143        synchronized(this) {
11144            if (mBackupAppName == null) {
11145                Slog.w(TAG, "Unbinding backup agent with no active backup");
11146                return;
11147            }
11148
11149            if (!mBackupAppName.equals(appInfo.packageName)) {
11150                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11151                return;
11152            }
11153
11154            ProcessRecord proc = mBackupTarget.app;
11155            mBackupTarget = null;
11156            mBackupAppName = null;
11157
11158            // Not backing this app up any more; reset its OOM adjustment
11159            updateOomAdjLocked(proc);
11160
11161            // If the app crashed during backup, 'thread' will be null here
11162            if (proc.thread != null) {
11163                try {
11164                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11165                            compatibilityInfoForPackageLocked(appInfo));
11166                } catch (Exception e) {
11167                    Slog.e(TAG, "Exception when unbinding backup agent:");
11168                    e.printStackTrace();
11169                }
11170            }
11171        }
11172    }
11173    // =========================================================
11174    // BROADCASTS
11175    // =========================================================
11176
11177    private final List getStickiesLocked(String action, IntentFilter filter,
11178            List cur, int userId) {
11179        final ContentResolver resolver = mContext.getContentResolver();
11180        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11181        if (stickies == null) {
11182            return cur;
11183        }
11184        final ArrayList<Intent> list = stickies.get(action);
11185        if (list == null) {
11186            return cur;
11187        }
11188        int N = list.size();
11189        for (int i=0; i<N; i++) {
11190            Intent intent = list.get(i);
11191            if (filter.match(resolver, intent, true, TAG) >= 0) {
11192                if (cur == null) {
11193                    cur = new ArrayList<Intent>();
11194                }
11195                cur.add(intent);
11196            }
11197        }
11198        return cur;
11199    }
11200
11201    boolean isPendingBroadcastProcessLocked(int pid) {
11202        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11203                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11204    }
11205
11206    void skipPendingBroadcastLocked(int pid) {
11207            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11208            for (BroadcastQueue queue : mBroadcastQueues) {
11209                queue.skipPendingBroadcastLocked(pid);
11210            }
11211    }
11212
11213    // The app just attached; send any pending broadcasts that it should receive
11214    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11215        boolean didSomething = false;
11216        for (BroadcastQueue queue : mBroadcastQueues) {
11217            didSomething |= queue.sendPendingBroadcastsLocked(app);
11218        }
11219        return didSomething;
11220    }
11221
11222    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11223            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11224        enforceNotIsolatedCaller("registerReceiver");
11225        int callingUid;
11226        int callingPid;
11227        synchronized(this) {
11228            ProcessRecord callerApp = null;
11229            if (caller != null) {
11230                callerApp = getRecordForAppLocked(caller);
11231                if (callerApp == null) {
11232                    throw new SecurityException(
11233                            "Unable to find app for caller " + caller
11234                            + " (pid=" + Binder.getCallingPid()
11235                            + ") when registering receiver " + receiver);
11236                }
11237                if (callerApp.info.uid != Process.SYSTEM_UID &&
11238                        !callerApp.pkgList.contains(callerPackage)) {
11239                    throw new SecurityException("Given caller package " + callerPackage
11240                            + " is not running in process " + callerApp);
11241                }
11242                callingUid = callerApp.info.uid;
11243                callingPid = callerApp.pid;
11244            } else {
11245                callerPackage = null;
11246                callingUid = Binder.getCallingUid();
11247                callingPid = Binder.getCallingPid();
11248            }
11249
11250            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11251                    true, true, "registerReceiver", callerPackage);
11252
11253            List allSticky = null;
11254
11255            // Look for any matching sticky broadcasts...
11256            Iterator actions = filter.actionsIterator();
11257            if (actions != null) {
11258                while (actions.hasNext()) {
11259                    String action = (String)actions.next();
11260                    allSticky = getStickiesLocked(action, filter, allSticky,
11261                            UserHandle.USER_ALL);
11262                    allSticky = getStickiesLocked(action, filter, allSticky,
11263                            UserHandle.getUserId(callingUid));
11264                }
11265            } else {
11266                allSticky = getStickiesLocked(null, filter, allSticky,
11267                        UserHandle.USER_ALL);
11268                allSticky = getStickiesLocked(null, filter, allSticky,
11269                        UserHandle.getUserId(callingUid));
11270            }
11271
11272            // The first sticky in the list is returned directly back to
11273            // the client.
11274            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11275
11276            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11277                    + ": " + sticky);
11278
11279            if (receiver == null) {
11280                return sticky;
11281            }
11282
11283            ReceiverList rl
11284                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11285            if (rl == null) {
11286                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11287                        userId, receiver);
11288                if (rl.app != null) {
11289                    rl.app.receivers.add(rl);
11290                } else {
11291                    try {
11292                        receiver.asBinder().linkToDeath(rl, 0);
11293                    } catch (RemoteException e) {
11294                        return sticky;
11295                    }
11296                    rl.linkedToDeath = true;
11297                }
11298                mRegisteredReceivers.put(receiver.asBinder(), rl);
11299            } else if (rl.uid != callingUid) {
11300                throw new IllegalArgumentException(
11301                        "Receiver requested to register for uid " + callingUid
11302                        + " was previously registered for uid " + rl.uid);
11303            } else if (rl.pid != callingPid) {
11304                throw new IllegalArgumentException(
11305                        "Receiver requested to register for pid " + callingPid
11306                        + " was previously registered for pid " + rl.pid);
11307            } else if (rl.userId != userId) {
11308                throw new IllegalArgumentException(
11309                        "Receiver requested to register for user " + userId
11310                        + " was previously registered for user " + rl.userId);
11311            }
11312            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11313                    permission, callingUid, userId);
11314            rl.add(bf);
11315            if (!bf.debugCheck()) {
11316                Slog.w(TAG, "==> For Dynamic broadast");
11317            }
11318            mReceiverResolver.addFilter(bf);
11319
11320            // Enqueue broadcasts for all existing stickies that match
11321            // this filter.
11322            if (allSticky != null) {
11323                ArrayList receivers = new ArrayList();
11324                receivers.add(bf);
11325
11326                int N = allSticky.size();
11327                for (int i=0; i<N; i++) {
11328                    Intent intent = (Intent)allSticky.get(i);
11329                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11330                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11331                            null, -1, -1, null, receivers, null, 0, null, null,
11332                            false, true, true, -1);
11333                    queue.enqueueParallelBroadcastLocked(r);
11334                    queue.scheduleBroadcastsLocked();
11335                }
11336            }
11337
11338            return sticky;
11339        }
11340    }
11341
11342    public void unregisterReceiver(IIntentReceiver receiver) {
11343        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11344
11345        final long origId = Binder.clearCallingIdentity();
11346        try {
11347            boolean doTrim = false;
11348
11349            synchronized(this) {
11350                ReceiverList rl
11351                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11352                if (rl != null) {
11353                    if (rl.curBroadcast != null) {
11354                        BroadcastRecord r = rl.curBroadcast;
11355                        final boolean doNext = finishReceiverLocked(
11356                                receiver.asBinder(), r.resultCode, r.resultData,
11357                                r.resultExtras, r.resultAbort, true);
11358                        if (doNext) {
11359                            doTrim = true;
11360                            r.queue.processNextBroadcast(false);
11361                        }
11362                    }
11363
11364                    if (rl.app != null) {
11365                        rl.app.receivers.remove(rl);
11366                    }
11367                    removeReceiverLocked(rl);
11368                    if (rl.linkedToDeath) {
11369                        rl.linkedToDeath = false;
11370                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11371                    }
11372                }
11373            }
11374
11375            // If we actually concluded any broadcasts, we might now be able
11376            // to trim the recipients' apps from our working set
11377            if (doTrim) {
11378                trimApplications();
11379                return;
11380            }
11381
11382        } finally {
11383            Binder.restoreCallingIdentity(origId);
11384        }
11385    }
11386
11387    void removeReceiverLocked(ReceiverList rl) {
11388        mRegisteredReceivers.remove(rl.receiver.asBinder());
11389        int N = rl.size();
11390        for (int i=0; i<N; i++) {
11391            mReceiverResolver.removeFilter(rl.get(i));
11392        }
11393    }
11394
11395    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11396        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11397            ProcessRecord r = mLruProcesses.get(i);
11398            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11399                try {
11400                    r.thread.dispatchPackageBroadcast(cmd, packages);
11401                } catch (RemoteException ex) {
11402                }
11403            }
11404        }
11405    }
11406
11407    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11408            int[] users) {
11409        List<ResolveInfo> receivers = null;
11410        try {
11411            HashSet<ComponentName> singleUserReceivers = null;
11412            boolean scannedFirstReceivers = false;
11413            for (int user : users) {
11414                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11415                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11416                if (newReceivers != null && newReceivers.size() == 0) {
11417                    newReceivers = null;
11418                }
11419                if (receivers == null) {
11420                    receivers = newReceivers;
11421                } else if (newReceivers != null) {
11422                    // We need to concatenate the additional receivers
11423                    // found with what we have do far.  This would be easy,
11424                    // but we also need to de-dup any receivers that are
11425                    // singleUser.
11426                    if (!scannedFirstReceivers) {
11427                        // Collect any single user receivers we had already retrieved.
11428                        scannedFirstReceivers = true;
11429                        for (int i=0; i<receivers.size(); i++) {
11430                            ResolveInfo ri = receivers.get(i);
11431                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11432                                ComponentName cn = new ComponentName(
11433                                        ri.activityInfo.packageName, ri.activityInfo.name);
11434                                if (singleUserReceivers == null) {
11435                                    singleUserReceivers = new HashSet<ComponentName>();
11436                                }
11437                                singleUserReceivers.add(cn);
11438                            }
11439                        }
11440                    }
11441                    // Add the new results to the existing results, tracking
11442                    // and de-dupping single user receivers.
11443                    for (int i=0; i<newReceivers.size(); i++) {
11444                        ResolveInfo ri = newReceivers.get(i);
11445                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11446                            ComponentName cn = new ComponentName(
11447                                    ri.activityInfo.packageName, ri.activityInfo.name);
11448                            if (singleUserReceivers == null) {
11449                                singleUserReceivers = new HashSet<ComponentName>();
11450                            }
11451                            if (!singleUserReceivers.contains(cn)) {
11452                                singleUserReceivers.add(cn);
11453                                receivers.add(ri);
11454                            }
11455                        } else {
11456                            receivers.add(ri);
11457                        }
11458                    }
11459                }
11460            }
11461        } catch (RemoteException ex) {
11462            // pm is in same process, this will never happen.
11463        }
11464        return receivers;
11465    }
11466
11467    private final int broadcastIntentLocked(ProcessRecord callerApp,
11468            String callerPackage, Intent intent, String resolvedType,
11469            IIntentReceiver resultTo, int resultCode, String resultData,
11470            Bundle map, String requiredPermission,
11471            boolean ordered, boolean sticky, int callingPid, int callingUid,
11472            int userId) {
11473        intent = new Intent(intent);
11474
11475        // By default broadcasts do not go to stopped apps.
11476        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11477
11478        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11479            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11480            + " ordered=" + ordered + " userid=" + userId);
11481        if ((resultTo != null) && !ordered) {
11482            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11483        }
11484
11485        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11486                true, false, "broadcast", callerPackage);
11487
11488        // Make sure that the user who is receiving this broadcast is started
11489        // If not, we will just skip it.
11490        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11491            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11492                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11493                Slog.w(TAG, "Skipping broadcast of " + intent
11494                        + ": user " + userId + " is stopped");
11495                return ActivityManager.BROADCAST_SUCCESS;
11496            }
11497        }
11498
11499        /*
11500         * Prevent non-system code (defined here to be non-persistent
11501         * processes) from sending protected broadcasts.
11502         */
11503        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11504            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11505            callingUid == 0) {
11506            // Always okay.
11507        } else if (callerApp == null || !callerApp.persistent) {
11508            try {
11509                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11510                        intent.getAction())) {
11511                    String msg = "Permission Denial: not allowed to send broadcast "
11512                            + intent.getAction() + " from pid="
11513                            + callingPid + ", uid=" + callingUid;
11514                    Slog.w(TAG, msg);
11515                    throw new SecurityException(msg);
11516                }
11517            } catch (RemoteException e) {
11518                Slog.w(TAG, "Remote exception", e);
11519                return ActivityManager.BROADCAST_SUCCESS;
11520            }
11521        }
11522
11523        // Handle special intents: if this broadcast is from the package
11524        // manager about a package being removed, we need to remove all of
11525        // its activities from the history stack.
11526        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11527                intent.getAction());
11528        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11529                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11530                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11531                || uidRemoved) {
11532            if (checkComponentPermission(
11533                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11534                    callingPid, callingUid, -1, true)
11535                    == PackageManager.PERMISSION_GRANTED) {
11536                if (uidRemoved) {
11537                    final Bundle intentExtras = intent.getExtras();
11538                    final int uid = intentExtras != null
11539                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11540                    if (uid >= 0) {
11541                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11542                        synchronized (bs) {
11543                            bs.removeUidStatsLocked(uid);
11544                        }
11545                    }
11546                } else {
11547                    // If resources are unavailable just force stop all
11548                    // those packages and flush the attribute cache as well.
11549                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11550                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11551                        if (list != null && (list.length > 0)) {
11552                            for (String pkg : list) {
11553                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11554                            }
11555                            sendPackageBroadcastLocked(
11556                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11557                        }
11558                    } else {
11559                        Uri data = intent.getData();
11560                        String ssp;
11561                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11562                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11563                                forceStopPackageLocked(ssp,
11564                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11565                                        false, userId);
11566                            }
11567                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11568                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11569                                        new String[] {ssp}, userId);
11570                            }
11571                        }
11572                    }
11573                }
11574            } else {
11575                String msg = "Permission Denial: " + intent.getAction()
11576                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11577                        + ", uid=" + callingUid + ")"
11578                        + " requires "
11579                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11580                Slog.w(TAG, msg);
11581                throw new SecurityException(msg);
11582            }
11583
11584        // Special case for adding a package: by default turn on compatibility
11585        // mode.
11586        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11587            Uri data = intent.getData();
11588            String ssp;
11589            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11590                mCompatModePackages.handlePackageAddedLocked(ssp,
11591                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11592            }
11593        }
11594
11595        /*
11596         * If this is the time zone changed action, queue up a message that will reset the timezone
11597         * of all currently running processes. This message will get queued up before the broadcast
11598         * happens.
11599         */
11600        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11601            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11602        }
11603
11604        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11605            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11606        }
11607
11608        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11609            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11610            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11611        }
11612
11613        // Add to the sticky list if requested.
11614        if (sticky) {
11615            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11616                    callingPid, callingUid)
11617                    != PackageManager.PERMISSION_GRANTED) {
11618                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11619                        + callingPid + ", uid=" + callingUid
11620                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11621                Slog.w(TAG, msg);
11622                throw new SecurityException(msg);
11623            }
11624            if (requiredPermission != null) {
11625                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11626                        + " and enforce permission " + requiredPermission);
11627                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11628            }
11629            if (intent.getComponent() != null) {
11630                throw new SecurityException(
11631                        "Sticky broadcasts can't target a specific component");
11632            }
11633            // We use userId directly here, since the "all" target is maintained
11634            // as a separate set of sticky broadcasts.
11635            if (userId != UserHandle.USER_ALL) {
11636                // But first, if this is not a broadcast to all users, then
11637                // make sure it doesn't conflict with an existing broadcast to
11638                // all users.
11639                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11640                        UserHandle.USER_ALL);
11641                if (stickies != null) {
11642                    ArrayList<Intent> list = stickies.get(intent.getAction());
11643                    if (list != null) {
11644                        int N = list.size();
11645                        int i;
11646                        for (i=0; i<N; i++) {
11647                            if (intent.filterEquals(list.get(i))) {
11648                                throw new IllegalArgumentException(
11649                                        "Sticky broadcast " + intent + " for user "
11650                                        + userId + " conflicts with existing global broadcast");
11651                            }
11652                        }
11653                    }
11654                }
11655            }
11656            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11657            if (stickies == null) {
11658                stickies = new HashMap<String, ArrayList<Intent>>();
11659                mStickyBroadcasts.put(userId, stickies);
11660            }
11661            ArrayList<Intent> list = stickies.get(intent.getAction());
11662            if (list == null) {
11663                list = new ArrayList<Intent>();
11664                stickies.put(intent.getAction(), list);
11665            }
11666            int N = list.size();
11667            int i;
11668            for (i=0; i<N; i++) {
11669                if (intent.filterEquals(list.get(i))) {
11670                    // This sticky already exists, replace it.
11671                    list.set(i, new Intent(intent));
11672                    break;
11673                }
11674            }
11675            if (i >= N) {
11676                list.add(new Intent(intent));
11677            }
11678        }
11679
11680        int[] users;
11681        if (userId == UserHandle.USER_ALL) {
11682            // Caller wants broadcast to go to all started users.
11683            users = new int[mStartedUsers.size()];
11684            for (int i=0; i<mStartedUsers.size(); i++) {
11685                users[i] = mStartedUsers.keyAt(i);
11686            }
11687        } else {
11688            // Caller wants broadcast to go to one specific user.
11689            users = new int[] {userId};
11690        }
11691
11692        // Figure out who all will receive this broadcast.
11693        List receivers = null;
11694        List<BroadcastFilter> registeredReceivers = null;
11695        // Need to resolve the intent to interested receivers...
11696        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11697                 == 0) {
11698            receivers = collectReceiverComponents(intent, resolvedType, users);
11699        }
11700        if (intent.getComponent() == null) {
11701            registeredReceivers = mReceiverResolver.queryIntent(intent,
11702                    resolvedType, false, userId);
11703        }
11704
11705        final boolean replacePending =
11706                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11707
11708        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11709                + " replacePending=" + replacePending);
11710
11711        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11712        if (!ordered && NR > 0) {
11713            // If we are not serializing this broadcast, then send the
11714            // registered receivers separately so they don't wait for the
11715            // components to be launched.
11716            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11717            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11718                    callerPackage, callingPid, callingUid, requiredPermission,
11719                    registeredReceivers, resultTo, resultCode, resultData, map,
11720                    ordered, sticky, false, userId);
11721            if (DEBUG_BROADCAST) Slog.v(
11722                    TAG, "Enqueueing parallel broadcast " + r);
11723            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11724            if (!replaced) {
11725                queue.enqueueParallelBroadcastLocked(r);
11726                queue.scheduleBroadcastsLocked();
11727            }
11728            registeredReceivers = null;
11729            NR = 0;
11730        }
11731
11732        // Merge into one list.
11733        int ir = 0;
11734        if (receivers != null) {
11735            // A special case for PACKAGE_ADDED: do not allow the package
11736            // being added to see this broadcast.  This prevents them from
11737            // using this as a back door to get run as soon as they are
11738            // installed.  Maybe in the future we want to have a special install
11739            // broadcast or such for apps, but we'd like to deliberately make
11740            // this decision.
11741            String skipPackages[] = null;
11742            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11743                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11744                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11745                Uri data = intent.getData();
11746                if (data != null) {
11747                    String pkgName = data.getSchemeSpecificPart();
11748                    if (pkgName != null) {
11749                        skipPackages = new String[] { pkgName };
11750                    }
11751                }
11752            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11753                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11754            }
11755            if (skipPackages != null && (skipPackages.length > 0)) {
11756                for (String skipPackage : skipPackages) {
11757                    if (skipPackage != null) {
11758                        int NT = receivers.size();
11759                        for (int it=0; it<NT; it++) {
11760                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11761                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11762                                receivers.remove(it);
11763                                it--;
11764                                NT--;
11765                            }
11766                        }
11767                    }
11768                }
11769            }
11770
11771            int NT = receivers != null ? receivers.size() : 0;
11772            int it = 0;
11773            ResolveInfo curt = null;
11774            BroadcastFilter curr = null;
11775            while (it < NT && ir < NR) {
11776                if (curt == null) {
11777                    curt = (ResolveInfo)receivers.get(it);
11778                }
11779                if (curr == null) {
11780                    curr = registeredReceivers.get(ir);
11781                }
11782                if (curr.getPriority() >= curt.priority) {
11783                    // Insert this broadcast record into the final list.
11784                    receivers.add(it, curr);
11785                    ir++;
11786                    curr = null;
11787                    it++;
11788                    NT++;
11789                } else {
11790                    // Skip to the next ResolveInfo in the final list.
11791                    it++;
11792                    curt = null;
11793                }
11794            }
11795        }
11796        while (ir < NR) {
11797            if (receivers == null) {
11798                receivers = new ArrayList();
11799            }
11800            receivers.add(registeredReceivers.get(ir));
11801            ir++;
11802        }
11803
11804        if ((receivers != null && receivers.size() > 0)
11805                || resultTo != null) {
11806            BroadcastQueue queue = broadcastQueueForIntent(intent);
11807            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11808                    callerPackage, callingPid, callingUid, requiredPermission,
11809                    receivers, resultTo, resultCode, resultData, map, ordered,
11810                    sticky, false, userId);
11811            if (DEBUG_BROADCAST) Slog.v(
11812                    TAG, "Enqueueing ordered broadcast " + r
11813                    + ": prev had " + queue.mOrderedBroadcasts.size());
11814            if (DEBUG_BROADCAST) {
11815                int seq = r.intent.getIntExtra("seq", -1);
11816                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11817            }
11818            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11819            if (!replaced) {
11820                queue.enqueueOrderedBroadcastLocked(r);
11821                queue.scheduleBroadcastsLocked();
11822            }
11823        }
11824
11825        return ActivityManager.BROADCAST_SUCCESS;
11826    }
11827
11828    final Intent verifyBroadcastLocked(Intent intent) {
11829        // Refuse possible leaked file descriptors
11830        if (intent != null && intent.hasFileDescriptors() == true) {
11831            throw new IllegalArgumentException("File descriptors passed in Intent");
11832        }
11833
11834        int flags = intent.getFlags();
11835
11836        if (!mProcessesReady) {
11837            // if the caller really truly claims to know what they're doing, go
11838            // ahead and allow the broadcast without launching any receivers
11839            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11840                intent = new Intent(intent);
11841                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11842            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11843                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11844                        + " before boot completion");
11845                throw new IllegalStateException("Cannot broadcast before boot completed");
11846            }
11847        }
11848
11849        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11850            throw new IllegalArgumentException(
11851                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11852        }
11853
11854        return intent;
11855    }
11856
11857    public final int broadcastIntent(IApplicationThread caller,
11858            Intent intent, String resolvedType, IIntentReceiver resultTo,
11859            int resultCode, String resultData, Bundle map,
11860            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11861        enforceNotIsolatedCaller("broadcastIntent");
11862        synchronized(this) {
11863            intent = verifyBroadcastLocked(intent);
11864
11865            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11866            final int callingPid = Binder.getCallingPid();
11867            final int callingUid = Binder.getCallingUid();
11868            final long origId = Binder.clearCallingIdentity();
11869            int res = broadcastIntentLocked(callerApp,
11870                    callerApp != null ? callerApp.info.packageName : null,
11871                    intent, resolvedType, resultTo,
11872                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11873                    callingPid, callingUid, userId);
11874            Binder.restoreCallingIdentity(origId);
11875            return res;
11876        }
11877    }
11878
11879    int broadcastIntentInPackage(String packageName, int uid,
11880            Intent intent, String resolvedType, IIntentReceiver resultTo,
11881            int resultCode, String resultData, Bundle map,
11882            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11883        synchronized(this) {
11884            intent = verifyBroadcastLocked(intent);
11885
11886            final long origId = Binder.clearCallingIdentity();
11887            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11888                    resultTo, resultCode, resultData, map, requiredPermission,
11889                    serialized, sticky, -1, uid, userId);
11890            Binder.restoreCallingIdentity(origId);
11891            return res;
11892        }
11893    }
11894
11895    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11896        // Refuse possible leaked file descriptors
11897        if (intent != null && intent.hasFileDescriptors() == true) {
11898            throw new IllegalArgumentException("File descriptors passed in Intent");
11899        }
11900
11901        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11902                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11903
11904        synchronized(this) {
11905            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11906                    != PackageManager.PERMISSION_GRANTED) {
11907                String msg = "Permission Denial: unbroadcastIntent() from pid="
11908                        + Binder.getCallingPid()
11909                        + ", uid=" + Binder.getCallingUid()
11910                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11911                Slog.w(TAG, msg);
11912                throw new SecurityException(msg);
11913            }
11914            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11915            if (stickies != null) {
11916                ArrayList<Intent> list = stickies.get(intent.getAction());
11917                if (list != null) {
11918                    int N = list.size();
11919                    int i;
11920                    for (i=0; i<N; i++) {
11921                        if (intent.filterEquals(list.get(i))) {
11922                            list.remove(i);
11923                            break;
11924                        }
11925                    }
11926                    if (list.size() <= 0) {
11927                        stickies.remove(intent.getAction());
11928                    }
11929                }
11930                if (stickies.size() <= 0) {
11931                    mStickyBroadcasts.remove(userId);
11932                }
11933            }
11934        }
11935    }
11936
11937    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11938            String resultData, Bundle resultExtras, boolean resultAbort,
11939            boolean explicit) {
11940        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11941        if (r == null) {
11942            Slog.w(TAG, "finishReceiver called but not found on queue");
11943            return false;
11944        }
11945
11946        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11947                explicit);
11948    }
11949
11950    public void finishReceiver(IBinder who, int resultCode, String resultData,
11951            Bundle resultExtras, boolean resultAbort) {
11952        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11953
11954        // Refuse possible leaked file descriptors
11955        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11956            throw new IllegalArgumentException("File descriptors passed in Bundle");
11957        }
11958
11959        final long origId = Binder.clearCallingIdentity();
11960        try {
11961            boolean doNext = false;
11962            BroadcastRecord r = null;
11963
11964            synchronized(this) {
11965                r = broadcastRecordForReceiverLocked(who);
11966                if (r != null) {
11967                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11968                        resultData, resultExtras, resultAbort, true);
11969                }
11970            }
11971
11972            if (doNext) {
11973                r.queue.processNextBroadcast(false);
11974            }
11975            trimApplications();
11976        } finally {
11977            Binder.restoreCallingIdentity(origId);
11978        }
11979    }
11980
11981    // =========================================================
11982    // INSTRUMENTATION
11983    // =========================================================
11984
11985    public boolean startInstrumentation(ComponentName className,
11986            String profileFile, int flags, Bundle arguments,
11987            IInstrumentationWatcher watcher, int userId) {
11988        enforceNotIsolatedCaller("startInstrumentation");
11989        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
11990                userId, false, true, "startInstrumentation", null);
11991        // Refuse possible leaked file descriptors
11992        if (arguments != null && arguments.hasFileDescriptors()) {
11993            throw new IllegalArgumentException("File descriptors passed in Bundle");
11994        }
11995
11996        synchronized(this) {
11997            InstrumentationInfo ii = null;
11998            ApplicationInfo ai = null;
11999            try {
12000                ii = mContext.getPackageManager().getInstrumentationInfo(
12001                    className, STOCK_PM_FLAGS);
12002                ai = AppGlobals.getPackageManager().getApplicationInfo(
12003                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12004            } catch (PackageManager.NameNotFoundException e) {
12005            } catch (RemoteException e) {
12006            }
12007            if (ii == null) {
12008                reportStartInstrumentationFailure(watcher, className,
12009                        "Unable to find instrumentation info for: " + className);
12010                return false;
12011            }
12012            if (ai == null) {
12013                reportStartInstrumentationFailure(watcher, className,
12014                        "Unable to find instrumentation target package: " + ii.targetPackage);
12015                return false;
12016            }
12017
12018            int match = mContext.getPackageManager().checkSignatures(
12019                    ii.targetPackage, ii.packageName);
12020            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12021                String msg = "Permission Denial: starting instrumentation "
12022                        + className + " from pid="
12023                        + Binder.getCallingPid()
12024                        + ", uid=" + Binder.getCallingPid()
12025                        + " not allowed because package " + ii.packageName
12026                        + " does not have a signature matching the target "
12027                        + ii.targetPackage;
12028                reportStartInstrumentationFailure(watcher, className, msg);
12029                throw new SecurityException(msg);
12030            }
12031
12032            final long origId = Binder.clearCallingIdentity();
12033            // Instrumentation can kill and relaunch even persistent processes
12034            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12035            ProcessRecord app = addAppLocked(ai, false);
12036            app.instrumentationClass = className;
12037            app.instrumentationInfo = ai;
12038            app.instrumentationProfileFile = profileFile;
12039            app.instrumentationArguments = arguments;
12040            app.instrumentationWatcher = watcher;
12041            app.instrumentationResultClass = className;
12042            Binder.restoreCallingIdentity(origId);
12043        }
12044
12045        return true;
12046    }
12047
12048    /**
12049     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12050     * error to the logs, but if somebody is watching, send the report there too.  This enables
12051     * the "am" command to report errors with more information.
12052     *
12053     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12054     * @param cn The component name of the instrumentation.
12055     * @param report The error report.
12056     */
12057    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12058            ComponentName cn, String report) {
12059        Slog.w(TAG, report);
12060        try {
12061            if (watcher != null) {
12062                Bundle results = new Bundle();
12063                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12064                results.putString("Error", report);
12065                watcher.instrumentationStatus(cn, -1, results);
12066            }
12067        } catch (RemoteException e) {
12068            Slog.w(TAG, e);
12069        }
12070    }
12071
12072    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12073        if (app.instrumentationWatcher != null) {
12074            try {
12075                // NOTE:  IInstrumentationWatcher *must* be oneway here
12076                app.instrumentationWatcher.instrumentationFinished(
12077                    app.instrumentationClass,
12078                    resultCode,
12079                    results);
12080            } catch (RemoteException e) {
12081            }
12082        }
12083        app.instrumentationWatcher = null;
12084        app.instrumentationClass = null;
12085        app.instrumentationInfo = null;
12086        app.instrumentationProfileFile = null;
12087        app.instrumentationArguments = null;
12088
12089        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12090    }
12091
12092    public void finishInstrumentation(IApplicationThread target,
12093            int resultCode, Bundle results) {
12094        int userId = UserHandle.getCallingUserId();
12095        // Refuse possible leaked file descriptors
12096        if (results != null && results.hasFileDescriptors()) {
12097            throw new IllegalArgumentException("File descriptors passed in Intent");
12098        }
12099
12100        synchronized(this) {
12101            ProcessRecord app = getRecordForAppLocked(target);
12102            if (app == null) {
12103                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12104                return;
12105            }
12106            final long origId = Binder.clearCallingIdentity();
12107            finishInstrumentationLocked(app, resultCode, results);
12108            Binder.restoreCallingIdentity(origId);
12109        }
12110    }
12111
12112    // =========================================================
12113    // CONFIGURATION
12114    // =========================================================
12115
12116    public ConfigurationInfo getDeviceConfigurationInfo() {
12117        ConfigurationInfo config = new ConfigurationInfo();
12118        synchronized (this) {
12119            config.reqTouchScreen = mConfiguration.touchscreen;
12120            config.reqKeyboardType = mConfiguration.keyboard;
12121            config.reqNavigation = mConfiguration.navigation;
12122            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12123                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12124                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12125            }
12126            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12127                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12128                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12129            }
12130            config.reqGlEsVersion = GL_ES_VERSION;
12131        }
12132        return config;
12133    }
12134
12135    public Configuration getConfiguration() {
12136        Configuration ci;
12137        synchronized(this) {
12138            ci = new Configuration(mConfiguration);
12139        }
12140        return ci;
12141    }
12142
12143    public void updatePersistentConfiguration(Configuration values) {
12144        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12145                "updateConfiguration()");
12146        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12147                "updateConfiguration()");
12148        if (values == null) {
12149            throw new NullPointerException("Configuration must not be null");
12150        }
12151
12152        synchronized(this) {
12153            final long origId = Binder.clearCallingIdentity();
12154            updateConfigurationLocked(values, null, true, false);
12155            Binder.restoreCallingIdentity(origId);
12156        }
12157    }
12158
12159    public void updateConfiguration(Configuration values) {
12160        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12161                "updateConfiguration()");
12162
12163        synchronized(this) {
12164            if (values == null && mWindowManager != null) {
12165                // sentinel: fetch the current configuration from the window manager
12166                values = mWindowManager.computeNewConfiguration();
12167            }
12168
12169            if (mWindowManager != null) {
12170                mProcessList.applyDisplaySize(mWindowManager);
12171            }
12172
12173            final long origId = Binder.clearCallingIdentity();
12174            if (values != null) {
12175                Settings.System.clearConfiguration(values);
12176            }
12177            updateConfigurationLocked(values, null, false, false);
12178            Binder.restoreCallingIdentity(origId);
12179        }
12180    }
12181
12182    /**
12183     * Do either or both things: (1) change the current configuration, and (2)
12184     * make sure the given activity is running with the (now) current
12185     * configuration.  Returns true if the activity has been left running, or
12186     * false if <var>starting</var> is being destroyed to match the new
12187     * configuration.
12188     * @param persistent TODO
12189     */
12190    boolean updateConfigurationLocked(Configuration values,
12191            ActivityRecord starting, boolean persistent, boolean initLocale) {
12192        // do nothing if we are headless
12193        if (mHeadless) return true;
12194
12195        int changes = 0;
12196
12197        boolean kept = true;
12198
12199        if (values != null) {
12200            Configuration newConfig = new Configuration(mConfiguration);
12201            changes = newConfig.updateFrom(values);
12202            if (changes != 0) {
12203                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12204                    Slog.i(TAG, "Updating configuration to: " + values);
12205                }
12206
12207                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12208
12209                if (values.locale != null && !initLocale) {
12210                    saveLocaleLocked(values.locale,
12211                                     !values.locale.equals(mConfiguration.locale),
12212                                     values.userSetLocale);
12213                }
12214
12215                mConfigurationSeq++;
12216                if (mConfigurationSeq <= 0) {
12217                    mConfigurationSeq = 1;
12218                }
12219                newConfig.seq = mConfigurationSeq;
12220                mConfiguration = newConfig;
12221                Slog.i(TAG, "Config changed: " + newConfig);
12222
12223                final Configuration configCopy = new Configuration(mConfiguration);
12224
12225                // TODO: If our config changes, should we auto dismiss any currently
12226                // showing dialogs?
12227                mShowDialogs = shouldShowDialogs(newConfig);
12228
12229                AttributeCache ac = AttributeCache.instance();
12230                if (ac != null) {
12231                    ac.updateConfiguration(configCopy);
12232                }
12233
12234                // Make sure all resources in our process are updated
12235                // right now, so that anyone who is going to retrieve
12236                // resource values after we return will be sure to get
12237                // the new ones.  This is especially important during
12238                // boot, where the first config change needs to guarantee
12239                // all resources have that config before following boot
12240                // code is executed.
12241                mSystemThread.applyConfigurationToResources(configCopy);
12242
12243                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12244                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12245                    msg.obj = new Configuration(configCopy);
12246                    mHandler.sendMessage(msg);
12247                }
12248
12249                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12250                    ProcessRecord app = mLruProcesses.get(i);
12251                    try {
12252                        if (app.thread != null) {
12253                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12254                                    + app.processName + " new config " + mConfiguration);
12255                            app.thread.scheduleConfigurationChanged(configCopy);
12256                        }
12257                    } catch (Exception e) {
12258                    }
12259                }
12260                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12261                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12262                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12263                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12264                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12265                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12266                    broadcastIntentLocked(null, null,
12267                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12268                            null, null, 0, null, null,
12269                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12270                }
12271            }
12272        }
12273
12274        if (changes != 0 && starting == null) {
12275            // If the configuration changed, and the caller is not already
12276            // in the process of starting an activity, then find the top
12277            // activity to check if its configuration needs to change.
12278            starting = mMainStack.topRunningActivityLocked(null);
12279        }
12280
12281        if (starting != null) {
12282            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12283            // And we need to make sure at this point that all other activities
12284            // are made visible with the correct configuration.
12285            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12286        }
12287
12288        if (values != null && mWindowManager != null) {
12289            mWindowManager.setNewConfiguration(mConfiguration);
12290        }
12291
12292        return kept;
12293    }
12294
12295    /**
12296     * Decide based on the configuration whether we should shouw the ANR,
12297     * crash, etc dialogs.  The idea is that if there is no affordnace to
12298     * press the on-screen buttons, we shouldn't show the dialog.
12299     *
12300     * A thought: SystemUI might also want to get told about this, the Power
12301     * dialog / global actions also might want different behaviors.
12302     */
12303    private static final boolean shouldShowDialogs(Configuration config) {
12304        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12305                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12306    }
12307
12308    /**
12309     * Save the locale.  You must be inside a synchronized (this) block.
12310     */
12311    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12312        if(isDiff) {
12313            SystemProperties.set("user.language", l.getLanguage());
12314            SystemProperties.set("user.region", l.getCountry());
12315        }
12316
12317        if(isPersist) {
12318            SystemProperties.set("persist.sys.language", l.getLanguage());
12319            SystemProperties.set("persist.sys.country", l.getCountry());
12320            SystemProperties.set("persist.sys.localevar", l.getVariant());
12321        }
12322    }
12323
12324    @Override
12325    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12326        ActivityRecord srec = ActivityRecord.forToken(token);
12327        return srec != null && srec.task.affinity != null &&
12328                srec.task.affinity.equals(destAffinity);
12329    }
12330
12331    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12332            Intent resultData) {
12333        ComponentName dest = destIntent.getComponent();
12334
12335        synchronized (this) {
12336            ActivityRecord srec = ActivityRecord.forToken(token);
12337            if (srec == null) {
12338                return false;
12339            }
12340            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12341            final int start = history.indexOf(srec);
12342            if (start < 0) {
12343                // Current activity is not in history stack; do nothing.
12344                return false;
12345            }
12346            int finishTo = start - 1;
12347            ActivityRecord parent = null;
12348            boolean foundParentInTask = false;
12349            if (dest != null) {
12350                TaskRecord tr = srec.task;
12351                for (int i = start - 1; i >= 0; i--) {
12352                    ActivityRecord r = history.get(i);
12353                    if (tr != r.task) {
12354                        // Couldn't find parent in the same task; stop at the one above this.
12355                        // (Root of current task; in-app "home" behavior)
12356                        // Always at least finish the current activity.
12357                        finishTo = Math.min(start - 1, i + 1);
12358                        parent = history.get(finishTo);
12359                        break;
12360                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12361                            r.info.name.equals(dest.getClassName())) {
12362                        finishTo = i;
12363                        parent = r;
12364                        foundParentInTask = true;
12365                        break;
12366                    }
12367                }
12368            }
12369
12370            if (mController != null) {
12371                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12372                if (next != null) {
12373                    // ask watcher if this is allowed
12374                    boolean resumeOK = true;
12375                    try {
12376                        resumeOK = mController.activityResuming(next.packageName);
12377                    } catch (RemoteException e) {
12378                        mController = null;
12379                    }
12380
12381                    if (!resumeOK) {
12382                        return false;
12383                    }
12384                }
12385            }
12386            final long origId = Binder.clearCallingIdentity();
12387            for (int i = start; i > finishTo; i--) {
12388                ActivityRecord r = history.get(i);
12389                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12390                        "navigate-up", true);
12391                // Only return the supplied result for the first activity finished
12392                resultCode = Activity.RESULT_CANCELED;
12393                resultData = null;
12394            }
12395
12396            if (parent != null && foundParentInTask) {
12397                final int parentLaunchMode = parent.info.launchMode;
12398                final int destIntentFlags = destIntent.getFlags();
12399                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12400                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12401                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12402                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12403                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12404                } else {
12405                    try {
12406                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12407                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12408                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12409                                null, aInfo, parent.appToken, null,
12410                                0, -1, parent.launchedFromUid, 0, null, true, null);
12411                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12412                    } catch (RemoteException e) {
12413                        foundParentInTask = false;
12414                    }
12415                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12416                            resultData, "navigate-up", true);
12417                }
12418            }
12419            Binder.restoreCallingIdentity(origId);
12420            return foundParentInTask;
12421        }
12422    }
12423
12424    public int getLaunchedFromUid(IBinder activityToken) {
12425        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12426        if (srec == null) {
12427            return -1;
12428        }
12429        return srec.launchedFromUid;
12430    }
12431
12432    // =========================================================
12433    // LIFETIME MANAGEMENT
12434    // =========================================================
12435
12436    // Returns which broadcast queue the app is the current [or imminent] receiver
12437    // on, or 'null' if the app is not an active broadcast recipient.
12438    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12439        BroadcastRecord r = app.curReceiver;
12440        if (r != null) {
12441            return r.queue;
12442        }
12443
12444        // It's not the current receiver, but it might be starting up to become one
12445        synchronized (this) {
12446            for (BroadcastQueue queue : mBroadcastQueues) {
12447                r = queue.mPendingBroadcast;
12448                if (r != null && r.curApp == app) {
12449                    // found it; report which queue it's in
12450                    return queue;
12451                }
12452            }
12453        }
12454
12455        return null;
12456    }
12457
12458    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12459            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12460        if (mAdjSeq == app.adjSeq) {
12461            // This adjustment has already been computed.  If we are calling
12462            // from the top, we may have already computed our adjustment with
12463            // an earlier hidden adjustment that isn't really for us... if
12464            // so, use the new hidden adjustment.
12465            if (!recursed && app.hidden) {
12466                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12467                        app.hasActivities ? hiddenAdj : emptyAdj;
12468            }
12469            return app.curRawAdj;
12470        }
12471
12472        if (app.thread == null) {
12473            app.adjSeq = mAdjSeq;
12474            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12475            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12476        }
12477
12478        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12479        app.adjSource = null;
12480        app.adjTarget = null;
12481        app.empty = false;
12482        app.hidden = false;
12483
12484        final int activitiesSize = app.activities.size();
12485
12486        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12487            // The max adjustment doesn't allow this app to be anything
12488            // below foreground, so it is not worth doing work for it.
12489            app.adjType = "fixed";
12490            app.adjSeq = mAdjSeq;
12491            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12492            app.hasActivities = false;
12493            app.foregroundActivities = false;
12494            app.keeping = true;
12495            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12496            // System process can do UI, and when they do we want to have
12497            // them trim their memory after the user leaves the UI.  To
12498            // facilitate this, here we need to determine whether or not it
12499            // is currently showing UI.
12500            app.systemNoUi = true;
12501            if (app == TOP_APP) {
12502                app.systemNoUi = false;
12503                app.hasActivities = true;
12504            } else if (activitiesSize > 0) {
12505                for (int j = 0; j < activitiesSize; j++) {
12506                    final ActivityRecord r = app.activities.get(j);
12507                    if (r.visible) {
12508                        app.systemNoUi = false;
12509                    }
12510                    if (r.app == app) {
12511                        app.hasActivities = true;
12512                    }
12513                }
12514            }
12515            return (app.curAdj=app.maxAdj);
12516        }
12517
12518        app.keeping = false;
12519        app.systemNoUi = false;
12520        app.hasActivities = false;
12521
12522        // Determine the importance of the process, starting with most
12523        // important to least, and assign an appropriate OOM adjustment.
12524        int adj;
12525        int schedGroup;
12526        boolean foregroundActivities = false;
12527        boolean interesting = false;
12528        BroadcastQueue queue;
12529        if (app == TOP_APP) {
12530            // The last app on the list is the foreground app.
12531            adj = ProcessList.FOREGROUND_APP_ADJ;
12532            schedGroup = Process.THREAD_GROUP_DEFAULT;
12533            app.adjType = "top-activity";
12534            foregroundActivities = true;
12535            interesting = true;
12536            app.hasActivities = true;
12537        } else if (app.instrumentationClass != null) {
12538            // Don't want to kill running instrumentation.
12539            adj = ProcessList.FOREGROUND_APP_ADJ;
12540            schedGroup = Process.THREAD_GROUP_DEFAULT;
12541            app.adjType = "instrumentation";
12542            interesting = true;
12543        } else if ((queue = isReceivingBroadcast(app)) != null) {
12544            // An app that is currently receiving a broadcast also
12545            // counts as being in the foreground for OOM killer purposes.
12546            // It's placed in a sched group based on the nature of the
12547            // broadcast as reflected by which queue it's active in.
12548            adj = ProcessList.FOREGROUND_APP_ADJ;
12549            schedGroup = (queue == mFgBroadcastQueue)
12550                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12551            app.adjType = "broadcast";
12552        } else if (app.executingServices.size() > 0) {
12553            // An app that is currently executing a service callback also
12554            // counts as being in the foreground.
12555            adj = ProcessList.FOREGROUND_APP_ADJ;
12556            schedGroup = Process.THREAD_GROUP_DEFAULT;
12557            app.adjType = "exec-service";
12558        } else {
12559            // Assume process is hidden (has activities); we will correct
12560            // later if this is not the case.
12561            adj = hiddenAdj;
12562            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12563            app.hidden = true;
12564            app.adjType = "bg-activities";
12565        }
12566
12567        boolean hasStoppingActivities = false;
12568
12569        // Examine all activities if not already foreground.
12570        if (!foregroundActivities && activitiesSize > 0) {
12571            for (int j = 0; j < activitiesSize; j++) {
12572                final ActivityRecord r = app.activities.get(j);
12573                if (r.visible) {
12574                    // App has a visible activity; only upgrade adjustment.
12575                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12576                        adj = ProcessList.VISIBLE_APP_ADJ;
12577                        app.adjType = "visible";
12578                    }
12579                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12580                    app.hidden = false;
12581                    app.hasActivities = true;
12582                    foregroundActivities = true;
12583                    break;
12584                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12585                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12586                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12587                        app.adjType = "pausing";
12588                    }
12589                    app.hidden = false;
12590                    foregroundActivities = true;
12591                } else if (r.state == ActivityState.STOPPING) {
12592                    // We will apply the actual adjustment later, because
12593                    // we want to allow this process to immediately go through
12594                    // any memory trimming that is in effect.
12595                    app.hidden = false;
12596                    foregroundActivities = true;
12597                    hasStoppingActivities = true;
12598                }
12599                if (r.app == app) {
12600                    app.hasActivities = true;
12601                }
12602            }
12603        }
12604
12605        if (adj == hiddenAdj && !app.hasActivities) {
12606            // Whoops, this process is completely empty as far as we know
12607            // at this point.
12608            adj = emptyAdj;
12609            app.empty = true;
12610            app.adjType = "bg-empty";
12611        }
12612
12613        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12614            if (app.foregroundServices) {
12615                // The user is aware of this app, so make it visible.
12616                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12617                app.hidden = false;
12618                app.adjType = "foreground-service";
12619                schedGroup = Process.THREAD_GROUP_DEFAULT;
12620            } else if (app.forcingToForeground != null) {
12621                // The user is aware of this app, so make it visible.
12622                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12623                app.hidden = false;
12624                app.adjType = "force-foreground";
12625                app.adjSource = app.forcingToForeground;
12626                schedGroup = Process.THREAD_GROUP_DEFAULT;
12627            }
12628        }
12629
12630        if (app.foregroundServices) {
12631            interesting = true;
12632        }
12633
12634        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12635            // We don't want to kill the current heavy-weight process.
12636            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12637            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12638            app.hidden = false;
12639            app.adjType = "heavy";
12640        }
12641
12642        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12643            // This process is hosting what we currently consider to be the
12644            // home app, so we don't want to let it go into the background.
12645            adj = ProcessList.HOME_APP_ADJ;
12646            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12647            app.hidden = false;
12648            app.adjType = "home";
12649        }
12650
12651        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12652                && app.activities.size() > 0) {
12653            // This was the previous process that showed UI to the user.
12654            // We want to try to keep it around more aggressively, to give
12655            // a good experience around switching between two apps.
12656            adj = ProcessList.PREVIOUS_APP_ADJ;
12657            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12658            app.hidden = false;
12659            app.adjType = "previous";
12660        }
12661
12662        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12663                + " reason=" + app.adjType);
12664
12665        // By default, we use the computed adjustment.  It may be changed if
12666        // there are applications dependent on our services or providers, but
12667        // this gives us a baseline and makes sure we don't get into an
12668        // infinite recursion.
12669        app.adjSeq = mAdjSeq;
12670        app.curRawAdj = app.nonStoppingAdj = adj;
12671
12672        if (mBackupTarget != null && app == mBackupTarget.app) {
12673            // If possible we want to avoid killing apps while they're being backed up
12674            if (adj > ProcessList.BACKUP_APP_ADJ) {
12675                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12676                adj = ProcessList.BACKUP_APP_ADJ;
12677                app.adjType = "backup";
12678                app.hidden = false;
12679            }
12680        }
12681
12682        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12683                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12684            final long now = SystemClock.uptimeMillis();
12685            // This process is more important if the top activity is
12686            // bound to the service.
12687            Iterator<ServiceRecord> jt = app.services.iterator();
12688            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12689                ServiceRecord s = jt.next();
12690                if (s.startRequested) {
12691                    if (app.hasShownUi && app != mHomeProcess) {
12692                        // If this process has shown some UI, let it immediately
12693                        // go to the LRU list because it may be pretty heavy with
12694                        // UI stuff.  We'll tag it with a label just to help
12695                        // debug and understand what is going on.
12696                        if (adj > ProcessList.SERVICE_ADJ) {
12697                            app.adjType = "started-bg-ui-services";
12698                        }
12699                    } else {
12700                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12701                            // This service has seen some activity within
12702                            // recent memory, so we will keep its process ahead
12703                            // of the background processes.
12704                            if (adj > ProcessList.SERVICE_ADJ) {
12705                                adj = ProcessList.SERVICE_ADJ;
12706                                app.adjType = "started-services";
12707                                app.hidden = false;
12708                            }
12709                        }
12710                        // If we have let the service slide into the background
12711                        // state, still have some text describing what it is doing
12712                        // even though the service no longer has an impact.
12713                        if (adj > ProcessList.SERVICE_ADJ) {
12714                            app.adjType = "started-bg-services";
12715                        }
12716                    }
12717                    // Don't kill this process because it is doing work; it
12718                    // has said it is doing work.
12719                    app.keeping = true;
12720                }
12721                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12722                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12723                    Iterator<ArrayList<ConnectionRecord>> kt
12724                            = s.connections.values().iterator();
12725                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12726                        ArrayList<ConnectionRecord> clist = kt.next();
12727                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12728                            // XXX should compute this based on the max of
12729                            // all connected clients.
12730                            ConnectionRecord cr = clist.get(i);
12731                            if (cr.binding.client == app) {
12732                                // Binding to ourself is not interesting.
12733                                continue;
12734                            }
12735                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12736                                ProcessRecord client = cr.binding.client;
12737                                int clientAdj = adj;
12738                                int myHiddenAdj = hiddenAdj;
12739                                if (myHiddenAdj > client.hiddenAdj) {
12740                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12741                                        myHiddenAdj = client.hiddenAdj;
12742                                    } else {
12743                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12744                                    }
12745                                }
12746                                int myEmptyAdj = emptyAdj;
12747                                if (myEmptyAdj > client.emptyAdj) {
12748                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12749                                        myEmptyAdj = client.emptyAdj;
12750                                    } else {
12751                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12752                                    }
12753                                }
12754                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12755                                        myEmptyAdj, TOP_APP, true, doingAll);
12756                                String adjType = null;
12757                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12758                                    // Not doing bind OOM management, so treat
12759                                    // this guy more like a started service.
12760                                    if (app.hasShownUi && app != mHomeProcess) {
12761                                        // If this process has shown some UI, let it immediately
12762                                        // go to the LRU list because it may be pretty heavy with
12763                                        // UI stuff.  We'll tag it with a label just to help
12764                                        // debug and understand what is going on.
12765                                        if (adj > clientAdj) {
12766                                            adjType = "bound-bg-ui-services";
12767                                        }
12768                                        app.hidden = false;
12769                                        clientAdj = adj;
12770                                    } else {
12771                                        if (now >= (s.lastActivity
12772                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12773                                            // This service has not seen activity within
12774                                            // recent memory, so allow it to drop to the
12775                                            // LRU list if there is no other reason to keep
12776                                            // it around.  We'll also tag it with a label just
12777                                            // to help debug and undertand what is going on.
12778                                            if (adj > clientAdj) {
12779                                                adjType = "bound-bg-services";
12780                                            }
12781                                            clientAdj = adj;
12782                                        }
12783                                    }
12784                                }
12785                                if (adj > clientAdj) {
12786                                    // If this process has recently shown UI, and
12787                                    // the process that is binding to it is less
12788                                    // important than being visible, then we don't
12789                                    // care about the binding as much as we care
12790                                    // about letting this process get into the LRU
12791                                    // list to be killed and restarted if needed for
12792                                    // memory.
12793                                    if (app.hasShownUi && app != mHomeProcess
12794                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12795                                        adjType = "bound-bg-ui-services";
12796                                    } else {
12797                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12798                                                |Context.BIND_IMPORTANT)) != 0) {
12799                                            adj = clientAdj;
12800                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12801                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12802                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12803                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12804                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12805                                            adj = clientAdj;
12806                                        } else {
12807                                            app.pendingUiClean = true;
12808                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12809                                                adj = ProcessList.VISIBLE_APP_ADJ;
12810                                            }
12811                                        }
12812                                        if (!client.hidden) {
12813                                            app.hidden = false;
12814                                        }
12815                                        if (client.keeping) {
12816                                            app.keeping = true;
12817                                        }
12818                                        adjType = "service";
12819                                    }
12820                                }
12821                                if (adjType != null) {
12822                                    app.adjType = adjType;
12823                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12824                                            .REASON_SERVICE_IN_USE;
12825                                    app.adjSource = cr.binding.client;
12826                                    app.adjSourceOom = clientAdj;
12827                                    app.adjTarget = s.name;
12828                                }
12829                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12830                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12831                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12832                                    }
12833                                }
12834                            }
12835                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12836                                ActivityRecord a = cr.activity;
12837                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12838                                        (a.visible || a.state == ActivityState.RESUMED
12839                                         || a.state == ActivityState.PAUSING)) {
12840                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12841                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12842                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12843                                    }
12844                                    app.hidden = false;
12845                                    app.adjType = "service";
12846                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12847                                            .REASON_SERVICE_IN_USE;
12848                                    app.adjSource = a;
12849                                    app.adjSourceOom = adj;
12850                                    app.adjTarget = s.name;
12851                                }
12852                            }
12853                        }
12854                    }
12855                }
12856            }
12857
12858            // Finally, if this process has active services running in it, we
12859            // would like to avoid killing it unless it would prevent the current
12860            // application from running.  By default we put the process in
12861            // with the rest of the background processes; as we scan through
12862            // its services we may bump it up from there.
12863            if (adj > hiddenAdj) {
12864                adj = hiddenAdj;
12865                app.hidden = false;
12866                app.adjType = "bg-services";
12867            }
12868        }
12869
12870        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12871                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12872            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12873            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12874                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12875                ContentProviderRecord cpr = jt.next();
12876                for (int i = cpr.connections.size()-1;
12877                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12878                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12879                        i--) {
12880                    ContentProviderConnection conn = cpr.connections.get(i);
12881                    ProcessRecord client = conn.client;
12882                    if (client == app) {
12883                        // Being our own client is not interesting.
12884                        continue;
12885                    }
12886                    int myHiddenAdj = hiddenAdj;
12887                    if (myHiddenAdj > client.hiddenAdj) {
12888                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12889                            myHiddenAdj = client.hiddenAdj;
12890                        } else {
12891                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12892                        }
12893                    }
12894                    int myEmptyAdj = emptyAdj;
12895                    if (myEmptyAdj > client.emptyAdj) {
12896                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12897                            myEmptyAdj = client.emptyAdj;
12898                        } else {
12899                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12900                        }
12901                    }
12902                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12903                            myEmptyAdj, TOP_APP, true, doingAll);
12904                    if (adj > clientAdj) {
12905                        if (app.hasShownUi && app != mHomeProcess
12906                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12907                            app.adjType = "bg-ui-provider";
12908                        } else {
12909                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12910                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12911                            app.adjType = "provider";
12912                        }
12913                        if (!client.hidden) {
12914                            app.hidden = false;
12915                        }
12916                        if (client.keeping) {
12917                            app.keeping = true;
12918                        }
12919                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12920                                .REASON_PROVIDER_IN_USE;
12921                        app.adjSource = client;
12922                        app.adjSourceOom = clientAdj;
12923                        app.adjTarget = cpr.name;
12924                    }
12925                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12926                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12927                    }
12928                }
12929                // If the provider has external (non-framework) process
12930                // dependencies, ensure that its adjustment is at least
12931                // FOREGROUND_APP_ADJ.
12932                if (cpr.hasExternalProcessHandles()) {
12933                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12934                        adj = ProcessList.FOREGROUND_APP_ADJ;
12935                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12936                        app.hidden = false;
12937                        app.keeping = true;
12938                        app.adjType = "provider";
12939                        app.adjTarget = cpr.name;
12940                    }
12941                }
12942            }
12943        }
12944
12945        if (adj == ProcessList.SERVICE_ADJ) {
12946            if (doingAll) {
12947                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12948                mNewNumServiceProcs++;
12949            }
12950            if (app.serviceb) {
12951                adj = ProcessList.SERVICE_B_ADJ;
12952            }
12953        } else {
12954            app.serviceb = false;
12955        }
12956
12957        app.nonStoppingAdj = adj;
12958
12959        if (hasStoppingActivities) {
12960            // Only upgrade adjustment.
12961            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12962                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12963                app.adjType = "stopping";
12964            }
12965        }
12966
12967        app.curRawAdj = adj;
12968
12969        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12970        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12971        if (adj > app.maxAdj) {
12972            adj = app.maxAdj;
12973            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12974                schedGroup = Process.THREAD_GROUP_DEFAULT;
12975            }
12976        }
12977        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12978            app.keeping = true;
12979        }
12980
12981        if (app.hasAboveClient) {
12982            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12983            // then we need to drop its adjustment to be lower than the service's
12984            // in order to honor the request.  We want to drop it by one adjustment
12985            // level...  but there is special meaning applied to various levels so
12986            // we will skip some of them.
12987            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12988                // System process will not get dropped, ever
12989            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12990                adj = ProcessList.VISIBLE_APP_ADJ;
12991            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12992                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12993            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12994                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12995            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12996                adj++;
12997            }
12998        }
12999
13000        int importance = app.memImportance;
13001        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13002            app.curAdj = adj;
13003            app.curSchedGroup = schedGroup;
13004            if (!interesting) {
13005                // For this reporting, if there is not something explicitly
13006                // interesting in this process then we will push it to the
13007                // background importance.
13008                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13009            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13010                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13011            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13012                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13013            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13014                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13015            } else if (adj >= ProcessList.SERVICE_ADJ) {
13016                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13017            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13018                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13019            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13020                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13021            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13022                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13023            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13024                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13025            } else {
13026                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13027            }
13028        }
13029
13030        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13031        if (foregroundActivities != app.foregroundActivities) {
13032            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13033        }
13034        if (changes != 0) {
13035            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13036            app.memImportance = importance;
13037            app.foregroundActivities = foregroundActivities;
13038            int i = mPendingProcessChanges.size()-1;
13039            ProcessChangeItem item = null;
13040            while (i >= 0) {
13041                item = mPendingProcessChanges.get(i);
13042                if (item.pid == app.pid) {
13043                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13044                    break;
13045                }
13046                i--;
13047            }
13048            if (i < 0) {
13049                // No existing item in pending changes; need a new one.
13050                final int NA = mAvailProcessChanges.size();
13051                if (NA > 0) {
13052                    item = mAvailProcessChanges.remove(NA-1);
13053                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13054                } else {
13055                    item = new ProcessChangeItem();
13056                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13057                }
13058                item.changes = 0;
13059                item.pid = app.pid;
13060                item.uid = app.info.uid;
13061                if (mPendingProcessChanges.size() == 0) {
13062                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13063                            "*** Enqueueing dispatch processes changed!");
13064                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13065                }
13066                mPendingProcessChanges.add(item);
13067            }
13068            item.changes |= changes;
13069            item.importance = importance;
13070            item.foregroundActivities = foregroundActivities;
13071            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13072                    + Integer.toHexString(System.identityHashCode(item))
13073                    + " " + app.toShortString() + ": changes=" + item.changes
13074                    + " importance=" + item.importance
13075                    + " foreground=" + item.foregroundActivities
13076                    + " type=" + app.adjType + " source=" + app.adjSource
13077                    + " target=" + app.adjTarget);
13078        }
13079
13080        return app.curRawAdj;
13081    }
13082
13083    /**
13084     * Ask a given process to GC right now.
13085     */
13086    final void performAppGcLocked(ProcessRecord app) {
13087        try {
13088            app.lastRequestedGc = SystemClock.uptimeMillis();
13089            if (app.thread != null) {
13090                if (app.reportLowMemory) {
13091                    app.reportLowMemory = false;
13092                    app.thread.scheduleLowMemory();
13093                } else {
13094                    app.thread.processInBackground();
13095                }
13096            }
13097        } catch (Exception e) {
13098            // whatever.
13099        }
13100    }
13101
13102    /**
13103     * Returns true if things are idle enough to perform GCs.
13104     */
13105    private final boolean canGcNowLocked() {
13106        boolean processingBroadcasts = false;
13107        for (BroadcastQueue q : mBroadcastQueues) {
13108            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13109                processingBroadcasts = true;
13110            }
13111        }
13112        return !processingBroadcasts
13113                && (mSleeping || (mMainStack.mResumedActivity != null &&
13114                        mMainStack.mResumedActivity.idle));
13115    }
13116
13117    /**
13118     * Perform GCs on all processes that are waiting for it, but only
13119     * if things are idle.
13120     */
13121    final void performAppGcsLocked() {
13122        final int N = mProcessesToGc.size();
13123        if (N <= 0) {
13124            return;
13125        }
13126        if (canGcNowLocked()) {
13127            while (mProcessesToGc.size() > 0) {
13128                ProcessRecord proc = mProcessesToGc.remove(0);
13129                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13130                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13131                            <= SystemClock.uptimeMillis()) {
13132                        // To avoid spamming the system, we will GC processes one
13133                        // at a time, waiting a few seconds between each.
13134                        performAppGcLocked(proc);
13135                        scheduleAppGcsLocked();
13136                        return;
13137                    } else {
13138                        // It hasn't been long enough since we last GCed this
13139                        // process...  put it in the list to wait for its time.
13140                        addProcessToGcListLocked(proc);
13141                        break;
13142                    }
13143                }
13144            }
13145
13146            scheduleAppGcsLocked();
13147        }
13148    }
13149
13150    /**
13151     * If all looks good, perform GCs on all processes waiting for them.
13152     */
13153    final void performAppGcsIfAppropriateLocked() {
13154        if (canGcNowLocked()) {
13155            performAppGcsLocked();
13156            return;
13157        }
13158        // Still not idle, wait some more.
13159        scheduleAppGcsLocked();
13160    }
13161
13162    /**
13163     * Schedule the execution of all pending app GCs.
13164     */
13165    final void scheduleAppGcsLocked() {
13166        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13167
13168        if (mProcessesToGc.size() > 0) {
13169            // Schedule a GC for the time to the next process.
13170            ProcessRecord proc = mProcessesToGc.get(0);
13171            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13172
13173            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13174            long now = SystemClock.uptimeMillis();
13175            if (when < (now+GC_TIMEOUT)) {
13176                when = now + GC_TIMEOUT;
13177            }
13178            mHandler.sendMessageAtTime(msg, when);
13179        }
13180    }
13181
13182    /**
13183     * Add a process to the array of processes waiting to be GCed.  Keeps the
13184     * list in sorted order by the last GC time.  The process can't already be
13185     * on the list.
13186     */
13187    final void addProcessToGcListLocked(ProcessRecord proc) {
13188        boolean added = false;
13189        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13190            if (mProcessesToGc.get(i).lastRequestedGc <
13191                    proc.lastRequestedGc) {
13192                added = true;
13193                mProcessesToGc.add(i+1, proc);
13194                break;
13195            }
13196        }
13197        if (!added) {
13198            mProcessesToGc.add(0, proc);
13199        }
13200    }
13201
13202    /**
13203     * Set up to ask a process to GC itself.  This will either do it
13204     * immediately, or put it on the list of processes to gc the next
13205     * time things are idle.
13206     */
13207    final void scheduleAppGcLocked(ProcessRecord app) {
13208        long now = SystemClock.uptimeMillis();
13209        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13210            return;
13211        }
13212        if (!mProcessesToGc.contains(app)) {
13213            addProcessToGcListLocked(app);
13214            scheduleAppGcsLocked();
13215        }
13216    }
13217
13218    final void checkExcessivePowerUsageLocked(boolean doKills) {
13219        updateCpuStatsNow();
13220
13221        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13222        boolean doWakeKills = doKills;
13223        boolean doCpuKills = doKills;
13224        if (mLastPowerCheckRealtime == 0) {
13225            doWakeKills = false;
13226        }
13227        if (mLastPowerCheckUptime == 0) {
13228            doCpuKills = false;
13229        }
13230        if (stats.isScreenOn()) {
13231            doWakeKills = false;
13232        }
13233        final long curRealtime = SystemClock.elapsedRealtime();
13234        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13235        final long curUptime = SystemClock.uptimeMillis();
13236        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13237        mLastPowerCheckRealtime = curRealtime;
13238        mLastPowerCheckUptime = curUptime;
13239        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13240            doWakeKills = false;
13241        }
13242        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13243            doCpuKills = false;
13244        }
13245        int i = mLruProcesses.size();
13246        while (i > 0) {
13247            i--;
13248            ProcessRecord app = mLruProcesses.get(i);
13249            if (!app.keeping) {
13250                long wtime;
13251                synchronized (stats) {
13252                    wtime = stats.getProcessWakeTime(app.info.uid,
13253                            app.pid, curRealtime);
13254                }
13255                long wtimeUsed = wtime - app.lastWakeTime;
13256                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13257                if (DEBUG_POWER) {
13258                    StringBuilder sb = new StringBuilder(128);
13259                    sb.append("Wake for ");
13260                    app.toShortString(sb);
13261                    sb.append(": over ");
13262                    TimeUtils.formatDuration(realtimeSince, sb);
13263                    sb.append(" used ");
13264                    TimeUtils.formatDuration(wtimeUsed, sb);
13265                    sb.append(" (");
13266                    sb.append((wtimeUsed*100)/realtimeSince);
13267                    sb.append("%)");
13268                    Slog.i(TAG, sb.toString());
13269                    sb.setLength(0);
13270                    sb.append("CPU for ");
13271                    app.toShortString(sb);
13272                    sb.append(": over ");
13273                    TimeUtils.formatDuration(uptimeSince, sb);
13274                    sb.append(" used ");
13275                    TimeUtils.formatDuration(cputimeUsed, sb);
13276                    sb.append(" (");
13277                    sb.append((cputimeUsed*100)/uptimeSince);
13278                    sb.append("%)");
13279                    Slog.i(TAG, sb.toString());
13280                }
13281                // If a process has held a wake lock for more
13282                // than 50% of the time during this period,
13283                // that sounds bad.  Kill!
13284                if (doWakeKills && realtimeSince > 0
13285                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13286                    synchronized (stats) {
13287                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13288                                realtimeSince, wtimeUsed);
13289                    }
13290                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13291                            + " (pid " + app.pid + "): held " + wtimeUsed
13292                            + " during " + realtimeSince);
13293                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13294                            app.processName, app.setAdj, "excessive wake lock");
13295                    Process.killProcessQuiet(app.pid);
13296                } else if (doCpuKills && uptimeSince > 0
13297                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13298                    synchronized (stats) {
13299                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13300                                uptimeSince, cputimeUsed);
13301                    }
13302                    Slog.w(TAG, "Excessive CPU in " + app.processName
13303                            + " (pid " + app.pid + "): used " + cputimeUsed
13304                            + " during " + uptimeSince);
13305                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13306                            app.processName, app.setAdj, "excessive cpu");
13307                    Process.killProcessQuiet(app.pid);
13308                } else {
13309                    app.lastWakeTime = wtime;
13310                    app.lastCpuTime = app.curCpuTime;
13311                }
13312            }
13313        }
13314    }
13315
13316    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13317            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13318        app.hiddenAdj = hiddenAdj;
13319        app.emptyAdj = emptyAdj;
13320
13321        if (app.thread == null) {
13322            return false;
13323        }
13324
13325        final boolean wasKeeping = app.keeping;
13326
13327        boolean success = true;
13328
13329        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13330
13331        if (app.curRawAdj != app.setRawAdj) {
13332            if (wasKeeping && !app.keeping) {
13333                // This app is no longer something we want to keep.  Note
13334                // its current wake lock time to later know to kill it if
13335                // it is not behaving well.
13336                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13337                synchronized (stats) {
13338                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13339                            app.pid, SystemClock.elapsedRealtime());
13340                }
13341                app.lastCpuTime = app.curCpuTime;
13342            }
13343
13344            app.setRawAdj = app.curRawAdj;
13345        }
13346
13347        if (app.curAdj != app.setAdj) {
13348            if (Process.setOomAdj(app.pid, app.curAdj)) {
13349                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13350                    TAG, "Set " + app.pid + " " + app.processName +
13351                    " adj " + app.curAdj + ": " + app.adjType);
13352                app.setAdj = app.curAdj;
13353            } else {
13354                success = false;
13355                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13356            }
13357        }
13358        if (app.setSchedGroup != app.curSchedGroup) {
13359            app.setSchedGroup = app.curSchedGroup;
13360            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13361                    "Setting process group of " + app.processName
13362                    + " to " + app.curSchedGroup);
13363            if (app.waitingToKill != null &&
13364                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13365                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13366                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13367                        app.processName, app.setAdj, app.waitingToKill);
13368                app.killedBackground = true;
13369                Process.killProcessQuiet(app.pid);
13370                success = false;
13371            } else {
13372                if (true) {
13373                    long oldId = Binder.clearCallingIdentity();
13374                    try {
13375                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13376                    } catch (Exception e) {
13377                        Slog.w(TAG, "Failed setting process group of " + app.pid
13378                                + " to " + app.curSchedGroup);
13379                        e.printStackTrace();
13380                    } finally {
13381                        Binder.restoreCallingIdentity(oldId);
13382                    }
13383                } else {
13384                    if (app.thread != null) {
13385                        try {
13386                            app.thread.setSchedulingGroup(app.curSchedGroup);
13387                        } catch (RemoteException e) {
13388                        }
13389                    }
13390                }
13391            }
13392        }
13393        return success;
13394    }
13395
13396    private final ActivityRecord resumedAppLocked() {
13397        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13398        if (resumedActivity == null || resumedActivity.app == null) {
13399            resumedActivity = mMainStack.mPausingActivity;
13400            if (resumedActivity == null || resumedActivity.app == null) {
13401                resumedActivity = mMainStack.topRunningActivityLocked(null);
13402            }
13403        }
13404        return resumedActivity;
13405    }
13406
13407    final boolean updateOomAdjLocked(ProcessRecord app) {
13408        final ActivityRecord TOP_ACT = resumedAppLocked();
13409        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13410        int curAdj = app.curAdj;
13411        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13412            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13413
13414        mAdjSeq++;
13415
13416        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13417                TOP_APP, false);
13418        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13419            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13420        if (nowHidden != wasHidden) {
13421            // Changed to/from hidden state, so apps after it in the LRU
13422            // list may also be changed.
13423            updateOomAdjLocked();
13424        }
13425        return success;
13426    }
13427
13428    final void updateOomAdjLocked() {
13429        final ActivityRecord TOP_ACT = resumedAppLocked();
13430        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13431
13432        if (false) {
13433            RuntimeException e = new RuntimeException();
13434            e.fillInStackTrace();
13435            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13436        }
13437
13438        mAdjSeq++;
13439        mNewNumServiceProcs = 0;
13440
13441        // Let's determine how many processes we have running vs.
13442        // how many slots we have for background processes; we may want
13443        // to put multiple processes in a slot of there are enough of
13444        // them.
13445        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13446                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13447        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13448        if (emptyFactor < 1) emptyFactor = 1;
13449        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13450        if (hiddenFactor < 1) hiddenFactor = 1;
13451        int stepHidden = 0;
13452        int stepEmpty = 0;
13453        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13454        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13455        int numHidden = 0;
13456        int numEmpty = 0;
13457        int numTrimming = 0;
13458
13459        mNumNonHiddenProcs = 0;
13460        mNumHiddenProcs = 0;
13461
13462        // First update the OOM adjustment for each of the
13463        // application processes based on their current state.
13464        int i = mLruProcesses.size();
13465        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13466        int nextHiddenAdj = curHiddenAdj+1;
13467        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13468        int nextEmptyAdj = curEmptyAdj+2;
13469        while (i > 0) {
13470            i--;
13471            ProcessRecord app = mLruProcesses.get(i);
13472            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13473            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13474            if (!app.killedBackground) {
13475                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13476                    // This process was assigned as a hidden process...  step the
13477                    // hidden level.
13478                    mNumHiddenProcs++;
13479                    if (curHiddenAdj != nextHiddenAdj) {
13480                        stepHidden++;
13481                        if (stepHidden >= hiddenFactor) {
13482                            stepHidden = 0;
13483                            curHiddenAdj = nextHiddenAdj;
13484                            nextHiddenAdj += 2;
13485                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13486                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13487                            }
13488                        }
13489                    }
13490                    numHidden++;
13491                    if (numHidden > hiddenProcessLimit) {
13492                        Slog.i(TAG, "No longer want " + app.processName
13493                                + " (pid " + app.pid + "): hidden #" + numHidden);
13494                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13495                                app.processName, app.setAdj, "too many background");
13496                        app.killedBackground = true;
13497                        Process.killProcessQuiet(app.pid);
13498                    }
13499                } else {
13500                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13501                        // This process was assigned as an empty process...  step the
13502                        // empty level.
13503                        if (curEmptyAdj != nextEmptyAdj) {
13504                            stepEmpty++;
13505                            if (stepEmpty >= emptyFactor) {
13506                                stepEmpty = 0;
13507                                curEmptyAdj = nextEmptyAdj;
13508                                nextEmptyAdj += 2;
13509                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13510                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13511                                }
13512                            }
13513                        }
13514                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13515                        mNumNonHiddenProcs++;
13516                    }
13517                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13518                        numEmpty++;
13519                        if (numEmpty > emptyProcessLimit) {
13520                            Slog.i(TAG, "No longer want " + app.processName
13521                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13522                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13523                                    app.processName, app.setAdj, "too many background");
13524                            app.killedBackground = true;
13525                            Process.killProcessQuiet(app.pid);
13526                        }
13527                    }
13528                }
13529                if (app.isolated && app.services.size() <= 0) {
13530                    // If this is an isolated process, and there are no
13531                    // services running in it, then the process is no longer
13532                    // needed.  We agressively kill these because we can by
13533                    // definition not re-use the same process again, and it is
13534                    // good to avoid having whatever code was running in them
13535                    // left sitting around after no longer needed.
13536                    Slog.i(TAG, "Isolated process " + app.processName
13537                            + " (pid " + app.pid + ") no longer needed");
13538                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13539                            app.processName, app.setAdj, "isolated not needed");
13540                    app.killedBackground = true;
13541                    Process.killProcessQuiet(app.pid);
13542                }
13543                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13544                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13545                        && !app.killedBackground) {
13546                    numTrimming++;
13547                }
13548            }
13549        }
13550
13551        mNumServiceProcs = mNewNumServiceProcs;
13552
13553        // Now determine the memory trimming level of background processes.
13554        // Unfortunately we need to start at the back of the list to do this
13555        // properly.  We only do this if the number of background apps we
13556        // are managing to keep around is less than half the maximum we desire;
13557        // if we are keeping a good number around, we'll let them use whatever
13558        // memory they want.
13559        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13560                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13561            final int numHiddenAndEmpty = numHidden + numEmpty;
13562            final int N = mLruProcesses.size();
13563            int factor = numTrimming/3;
13564            int minFactor = 2;
13565            if (mHomeProcess != null) minFactor++;
13566            if (mPreviousProcess != null) minFactor++;
13567            if (factor < minFactor) factor = minFactor;
13568            int step = 0;
13569            int fgTrimLevel;
13570            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13571                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13572            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13573                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13574            } else {
13575                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13576            }
13577            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13578            for (i=0; i<N; i++) {
13579                ProcessRecord app = mLruProcesses.get(i);
13580                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13581                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13582                        && !app.killedBackground) {
13583                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13584                        try {
13585                            app.thread.scheduleTrimMemory(curLevel);
13586                        } catch (RemoteException e) {
13587                        }
13588                        if (false) {
13589                            // For now we won't do this; our memory trimming seems
13590                            // to be good enough at this point that destroying
13591                            // activities causes more harm than good.
13592                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13593                                    && app != mHomeProcess && app != mPreviousProcess) {
13594                                // Need to do this on its own message because the stack may not
13595                                // be in a consistent state at this point.
13596                                // For these apps we will also finish their activities
13597                                // to help them free memory.
13598                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13599                            }
13600                        }
13601                    }
13602                    app.trimMemoryLevel = curLevel;
13603                    step++;
13604                    if (step >= factor) {
13605                        step = 0;
13606                        switch (curLevel) {
13607                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13608                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13609                                break;
13610                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13611                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13612                                break;
13613                        }
13614                    }
13615                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13616                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13617                            && app.thread != null) {
13618                        try {
13619                            app.thread.scheduleTrimMemory(
13620                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13621                        } catch (RemoteException e) {
13622                        }
13623                    }
13624                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13625                } else {
13626                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13627                            && app.pendingUiClean) {
13628                        // If this application is now in the background and it
13629                        // had done UI, then give it the special trim level to
13630                        // have it free UI resources.
13631                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13632                        if (app.trimMemoryLevel < level && app.thread != null) {
13633                            try {
13634                                app.thread.scheduleTrimMemory(level);
13635                            } catch (RemoteException e) {
13636                            }
13637                        }
13638                        app.pendingUiClean = false;
13639                    }
13640                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13641                        try {
13642                            app.thread.scheduleTrimMemory(fgTrimLevel);
13643                        } catch (RemoteException e) {
13644                        }
13645                    }
13646                    app.trimMemoryLevel = fgTrimLevel;
13647                }
13648            }
13649        } else {
13650            final int N = mLruProcesses.size();
13651            for (i=0; i<N; i++) {
13652                ProcessRecord app = mLruProcesses.get(i);
13653                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13654                        && app.pendingUiClean) {
13655                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13656                            && app.thread != null) {
13657                        try {
13658                            app.thread.scheduleTrimMemory(
13659                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13660                        } catch (RemoteException e) {
13661                        }
13662                    }
13663                    app.pendingUiClean = false;
13664                }
13665                app.trimMemoryLevel = 0;
13666            }
13667        }
13668
13669        if (mAlwaysFinishActivities) {
13670            // Need to do this on its own message because the stack may not
13671            // be in a consistent state at this point.
13672            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13673        }
13674    }
13675
13676    final void trimApplications() {
13677        synchronized (this) {
13678            int i;
13679
13680            // First remove any unused application processes whose package
13681            // has been removed.
13682            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13683                final ProcessRecord app = mRemovedProcesses.get(i);
13684                if (app.activities.size() == 0
13685                        && app.curReceiver == null && app.services.size() == 0) {
13686                    Slog.i(
13687                        TAG, "Exiting empty application process "
13688                        + app.processName + " ("
13689                        + (app.thread != null ? app.thread.asBinder() : null)
13690                        + ")\n");
13691                    if (app.pid > 0 && app.pid != MY_PID) {
13692                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13693                                app.processName, app.setAdj, "empty");
13694                        Process.killProcessQuiet(app.pid);
13695                    } else {
13696                        try {
13697                            app.thread.scheduleExit();
13698                        } catch (Exception e) {
13699                            // Ignore exceptions.
13700                        }
13701                    }
13702                    cleanUpApplicationRecordLocked(app, false, true, -1);
13703                    mRemovedProcesses.remove(i);
13704
13705                    if (app.persistent) {
13706                        if (app.persistent) {
13707                            addAppLocked(app.info, false);
13708                        }
13709                    }
13710                }
13711            }
13712
13713            // Now update the oom adj for all processes.
13714            updateOomAdjLocked();
13715        }
13716    }
13717
13718    /** This method sends the specified signal to each of the persistent apps */
13719    public void signalPersistentProcesses(int sig) throws RemoteException {
13720        if (sig != Process.SIGNAL_USR1) {
13721            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13722        }
13723
13724        synchronized (this) {
13725            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13726                    != PackageManager.PERMISSION_GRANTED) {
13727                throw new SecurityException("Requires permission "
13728                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13729            }
13730
13731            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13732                ProcessRecord r = mLruProcesses.get(i);
13733                if (r.thread != null && r.persistent) {
13734                    Process.sendSignal(r.pid, sig);
13735                }
13736            }
13737        }
13738    }
13739
13740    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13741        if (proc == null || proc == mProfileProc) {
13742            proc = mProfileProc;
13743            path = mProfileFile;
13744            profileType = mProfileType;
13745            clearProfilerLocked();
13746        }
13747        if (proc == null) {
13748            return;
13749        }
13750        try {
13751            proc.thread.profilerControl(false, path, null, profileType);
13752        } catch (RemoteException e) {
13753            throw new IllegalStateException("Process disappeared");
13754        }
13755    }
13756
13757    private void clearProfilerLocked() {
13758        if (mProfileFd != null) {
13759            try {
13760                mProfileFd.close();
13761            } catch (IOException e) {
13762            }
13763        }
13764        mProfileApp = null;
13765        mProfileProc = null;
13766        mProfileFile = null;
13767        mProfileType = 0;
13768        mAutoStopProfiler = false;
13769    }
13770
13771    public boolean profileControl(String process, int userId, boolean start,
13772            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13773
13774        try {
13775            synchronized (this) {
13776                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13777                // its own permission.
13778                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13779                        != PackageManager.PERMISSION_GRANTED) {
13780                    throw new SecurityException("Requires permission "
13781                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13782                }
13783
13784                if (start && fd == null) {
13785                    throw new IllegalArgumentException("null fd");
13786                }
13787
13788                ProcessRecord proc = null;
13789                if (process != null) {
13790                    proc = findProcessLocked(process, userId, "profileControl");
13791                }
13792
13793                if (start && (proc == null || proc.thread == null)) {
13794                    throw new IllegalArgumentException("Unknown process: " + process);
13795                }
13796
13797                if (start) {
13798                    stopProfilerLocked(null, null, 0);
13799                    setProfileApp(proc.info, proc.processName, path, fd, false);
13800                    mProfileProc = proc;
13801                    mProfileType = profileType;
13802                    try {
13803                        fd = fd.dup();
13804                    } catch (IOException e) {
13805                        fd = null;
13806                    }
13807                    proc.thread.profilerControl(start, path, fd, profileType);
13808                    fd = null;
13809                    mProfileFd = null;
13810                } else {
13811                    stopProfilerLocked(proc, path, profileType);
13812                    if (fd != null) {
13813                        try {
13814                            fd.close();
13815                        } catch (IOException e) {
13816                        }
13817                    }
13818                }
13819
13820                return true;
13821            }
13822        } catch (RemoteException e) {
13823            throw new IllegalStateException("Process disappeared");
13824        } finally {
13825            if (fd != null) {
13826                try {
13827                    fd.close();
13828                } catch (IOException e) {
13829                }
13830            }
13831        }
13832    }
13833
13834    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13835        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
13836                userId, true, true, callName, null);
13837        ProcessRecord proc = null;
13838        try {
13839            int pid = Integer.parseInt(process);
13840            synchronized (mPidsSelfLocked) {
13841                proc = mPidsSelfLocked.get(pid);
13842            }
13843        } catch (NumberFormatException e) {
13844        }
13845
13846        if (proc == null) {
13847            HashMap<String, SparseArray<ProcessRecord>> all
13848                    = mProcessNames.getMap();
13849            SparseArray<ProcessRecord> procs = all.get(process);
13850            if (procs != null && procs.size() > 0) {
13851                proc = procs.valueAt(0);
13852                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13853                    for (int i=1; i<procs.size(); i++) {
13854                        ProcessRecord thisProc = procs.valueAt(i);
13855                        if (thisProc.userId == userId) {
13856                            proc = thisProc;
13857                            break;
13858                        }
13859                    }
13860                }
13861            }
13862        }
13863
13864        return proc;
13865    }
13866
13867    public boolean dumpHeap(String process, int userId, boolean managed,
13868            String path, ParcelFileDescriptor fd) throws RemoteException {
13869
13870        try {
13871            synchronized (this) {
13872                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13873                // its own permission (same as profileControl).
13874                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13875                        != PackageManager.PERMISSION_GRANTED) {
13876                    throw new SecurityException("Requires permission "
13877                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13878                }
13879
13880                if (fd == null) {
13881                    throw new IllegalArgumentException("null fd");
13882                }
13883
13884                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13885                if (proc == null || proc.thread == null) {
13886                    throw new IllegalArgumentException("Unknown process: " + process);
13887                }
13888
13889                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13890                if (!isDebuggable) {
13891                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13892                        throw new SecurityException("Process not debuggable: " + proc);
13893                    }
13894                }
13895
13896                proc.thread.dumpHeap(managed, path, fd);
13897                fd = null;
13898                return true;
13899            }
13900        } catch (RemoteException e) {
13901            throw new IllegalStateException("Process disappeared");
13902        } finally {
13903            if (fd != null) {
13904                try {
13905                    fd.close();
13906                } catch (IOException e) {
13907                }
13908            }
13909        }
13910    }
13911
13912    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13913    public void monitor() {
13914        synchronized (this) { }
13915    }
13916
13917    void onCoreSettingsChange(Bundle settings) {
13918        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13919            ProcessRecord processRecord = mLruProcesses.get(i);
13920            try {
13921                if (processRecord.thread != null) {
13922                    processRecord.thread.setCoreSettings(settings);
13923                }
13924            } catch (RemoteException re) {
13925                /* ignore */
13926            }
13927        }
13928    }
13929
13930    // Multi-user methods
13931
13932    @Override
13933    public boolean switchUser(int userId) {
13934        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13935                != PackageManager.PERMISSION_GRANTED) {
13936            String msg = "Permission Denial: switchUser() from pid="
13937                    + Binder.getCallingPid()
13938                    + ", uid=" + Binder.getCallingUid()
13939                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13940            Slog.w(TAG, msg);
13941            throw new SecurityException(msg);
13942        }
13943
13944        final long ident = Binder.clearCallingIdentity();
13945        try {
13946            synchronized (this) {
13947                final int oldUserId = mCurrentUserId;
13948                if (oldUserId == userId) {
13949                    return true;
13950                }
13951
13952                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
13953                if (userInfo == null) {
13954                    Slog.w(TAG, "No user info for user #" + userId);
13955                    return false;
13956                }
13957
13958                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13959                        R.anim.screen_user_enter);
13960
13961                // If the user we are switching to is not currently started, then
13962                // we need to start it now.
13963                if (mStartedUsers.get(userId) == null) {
13964                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13965                }
13966
13967                mCurrentUserId = userId;
13968                final Integer userIdInt = Integer.valueOf(userId);
13969                mUserLru.remove(userIdInt);
13970                mUserLru.add(userIdInt);
13971
13972                mWindowManager.setCurrentUser(userId);
13973
13974                final UserStartedState uss = mStartedUsers.get(userId);
13975
13976                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
13977                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
13978                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
13979                        oldUserId, userId, uss));
13980                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
13981                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
13982                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13983                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13984                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13985                broadcastIntentLocked(null, null, intent,
13986                        null, null, 0, null, null, null,
13987                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13988
13989                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
13990                    if (userId != 0) {
13991                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
13992                        broadcastIntentLocked(null, null, intent, null,
13993                                new IIntentReceiver.Stub() {
13994                                    public void performReceive(Intent intent, int resultCode,
13995                                            String data, Bundle extras, boolean ordered,
13996                                            boolean sticky, int sendingUser) {
13997                                        synchronized (ActivityManagerService.this) {
13998                                            getUserManagerLocked().makeInitialized(userInfo.id);
13999                                        }
14000                                    }
14001                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14002                                userId);
14003                    } else {
14004                        getUserManagerLocked().makeInitialized(userInfo.id);
14005                    }
14006                }
14007
14008                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14009                if (!haveActivities) {
14010                    startHomeActivityLocked(userId);
14011                }
14012
14013                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14014            }
14015        } finally {
14016            Binder.restoreCallingIdentity(ident);
14017        }
14018
14019        return true;
14020    }
14021
14022    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14023        long ident = Binder.clearCallingIdentity();
14024        try {
14025            Intent intent;
14026            if (oldUserId >= 0) {
14027                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14028                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14029                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14030                broadcastIntentLocked(null, null, intent,
14031                        null, null, 0, null, null, null,
14032                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14033            }
14034            if (newUserId >= 0) {
14035                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14036                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14037                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14038                broadcastIntentLocked(null, null, intent,
14039                        null, null, 0, null, null, null,
14040                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14041                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14043                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14044                broadcastIntentLocked(null, null, intent,
14045                        null, null, 0, null, null,
14046                        android.Manifest.permission.MANAGE_USERS,
14047                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14048            }
14049        } finally {
14050            Binder.restoreCallingIdentity(ident);
14051        }
14052    }
14053
14054    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14055            final int newUserId) {
14056        final int N = mUserSwitchObservers.beginBroadcast();
14057        if (N > 0) {
14058            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14059                int mCount = 0;
14060                @Override
14061                public void sendResult(Bundle data) throws RemoteException {
14062                    synchronized (ActivityManagerService.this) {
14063                        if (mCurUserSwitchCallback == this) {
14064                            mCount++;
14065                            if (mCount == N) {
14066                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14067                            }
14068                        }
14069                    }
14070                }
14071            };
14072            synchronized (this) {
14073                mCurUserSwitchCallback = callback;
14074            }
14075            for (int i=0; i<N; i++) {
14076                try {
14077                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14078                            newUserId, callback);
14079                } catch (RemoteException e) {
14080                }
14081            }
14082        } else {
14083            synchronized (this) {
14084                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14085            }
14086        }
14087        mUserSwitchObservers.finishBroadcast();
14088    }
14089
14090    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14091        synchronized (this) {
14092            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14093            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14094        }
14095    }
14096
14097    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14098        mCurUserSwitchCallback = null;
14099        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14100        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14101                oldUserId, newUserId, uss));
14102    }
14103
14104    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14105        final int N = mUserSwitchObservers.beginBroadcast();
14106        for (int i=0; i<N; i++) {
14107            try {
14108                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14109            } catch (RemoteException e) {
14110            }
14111        }
14112        mUserSwitchObservers.finishBroadcast();
14113        synchronized (this) {
14114            mWindowManager.stopFreezingScreen();
14115        }
14116    }
14117
14118    void finishUserSwitch(UserStartedState uss) {
14119        synchronized (this) {
14120            if (uss.mState == UserStartedState.STATE_BOOTING
14121                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14122                uss.mState = UserStartedState.STATE_RUNNING;
14123                final int userId = uss.mHandle.getIdentifier();
14124                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14125                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14126                broadcastIntentLocked(null, null, intent,
14127                        null, null, 0, null, null,
14128                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14129                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14130            }
14131            int num = mUserLru.size();
14132            int i = 0;
14133            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14134                Integer oldUserId = mUserLru.get(i);
14135                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14136                if (oldUss == null) {
14137                    // Shouldn't happen, but be sane if it does.
14138                    mUserLru.remove(i);
14139                    num--;
14140                    continue;
14141                }
14142                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14143                    // This user is already stopping, doesn't count.
14144                    num--;
14145                    i++;
14146                    continue;
14147                }
14148                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14149                    // Owner and current can't be stopped, but count as running.
14150                    i++;
14151                    continue;
14152                }
14153                // This is a user to be stopped.
14154                stopUserLocked(oldUserId, null);
14155                num--;
14156                i++;
14157            }
14158        }
14159    }
14160
14161    @Override
14162    public int stopUser(final int userId, final IStopUserCallback callback) {
14163        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14164                != PackageManager.PERMISSION_GRANTED) {
14165            String msg = "Permission Denial: switchUser() from pid="
14166                    + Binder.getCallingPid()
14167                    + ", uid=" + Binder.getCallingUid()
14168                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14169            Slog.w(TAG, msg);
14170            throw new SecurityException(msg);
14171        }
14172        if (userId <= 0) {
14173            throw new IllegalArgumentException("Can't stop primary user " + userId);
14174        }
14175        synchronized (this) {
14176            return stopUserLocked(userId, callback);
14177        }
14178    }
14179
14180    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14181        if (mCurrentUserId == userId) {
14182            return ActivityManager.USER_OP_IS_CURRENT;
14183        }
14184
14185        final UserStartedState uss = mStartedUsers.get(userId);
14186        if (uss == null) {
14187            // User is not started, nothing to do...  but we do need to
14188            // callback if requested.
14189            if (callback != null) {
14190                mHandler.post(new Runnable() {
14191                    @Override
14192                    public void run() {
14193                        try {
14194                            callback.userStopped(userId);
14195                        } catch (RemoteException e) {
14196                        }
14197                    }
14198                });
14199            }
14200            return ActivityManager.USER_OP_SUCCESS;
14201        }
14202
14203        if (callback != null) {
14204            uss.mStopCallbacks.add(callback);
14205        }
14206
14207        if (uss.mState != UserStartedState.STATE_STOPPING) {
14208            uss.mState = UserStartedState.STATE_STOPPING;
14209
14210            long ident = Binder.clearCallingIdentity();
14211            try {
14212                // Inform of user switch
14213                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14214                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14215                    @Override
14216                    public void performReceive(Intent intent, int resultCode, String data,
14217                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14218                        finishUserStop(uss);
14219                    }
14220                };
14221                broadcastIntentLocked(null, null, intent,
14222                        null, resultReceiver, 0, null, null, null,
14223                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14224            } finally {
14225                Binder.restoreCallingIdentity(ident);
14226            }
14227        }
14228
14229        return ActivityManager.USER_OP_SUCCESS;
14230    }
14231
14232    void finishUserStop(UserStartedState uss) {
14233        final int userId = uss.mHandle.getIdentifier();
14234        boolean stopped;
14235        ArrayList<IStopUserCallback> callbacks;
14236        synchronized (this) {
14237            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14238            if (uss.mState != UserStartedState.STATE_STOPPING
14239                    || mStartedUsers.get(userId) != uss) {
14240                stopped = false;
14241            } else {
14242                stopped = true;
14243                // User can no longer run.
14244                mStartedUsers.remove(userId);
14245                mUserLru.remove(Integer.valueOf(userId));
14246
14247                // Clean up all state and processes associated with the user.
14248                // Kill all the processes for the user.
14249                forceStopUserLocked(userId);
14250            }
14251        }
14252
14253        for (int i=0; i<callbacks.size(); i++) {
14254            try {
14255                if (stopped) callbacks.get(i).userStopped(userId);
14256                else callbacks.get(i).userStopAborted(userId);
14257            } catch (RemoteException e) {
14258            }
14259        }
14260    }
14261
14262    @Override
14263    public UserInfo getCurrentUser() {
14264        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14265                != PackageManager.PERMISSION_GRANTED) && (
14266                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14267                != PackageManager.PERMISSION_GRANTED)) {
14268            String msg = "Permission Denial: getCurrentUser() from pid="
14269                    + Binder.getCallingPid()
14270                    + ", uid=" + Binder.getCallingUid()
14271                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14272            Slog.w(TAG, msg);
14273            throw new SecurityException(msg);
14274        }
14275        synchronized (this) {
14276            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14277        }
14278    }
14279
14280    @Override
14281    public boolean isUserRunning(int userId) {
14282        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14283                != PackageManager.PERMISSION_GRANTED) {
14284            String msg = "Permission Denial: isUserRunning() from pid="
14285                    + Binder.getCallingPid()
14286                    + ", uid=" + Binder.getCallingUid()
14287                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14288            Slog.w(TAG, msg);
14289            throw new SecurityException(msg);
14290        }
14291        synchronized (this) {
14292            return isUserRunningLocked(userId);
14293        }
14294    }
14295
14296    boolean isUserRunningLocked(int userId) {
14297        UserStartedState state = mStartedUsers.get(userId);
14298        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14299    }
14300
14301    @Override
14302    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14303        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14304                != PackageManager.PERMISSION_GRANTED) {
14305            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14306                    + Binder.getCallingPid()
14307                    + ", uid=" + Binder.getCallingUid()
14308                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14309            Slog.w(TAG, msg);
14310            throw new SecurityException(msg);
14311        }
14312
14313        mUserSwitchObservers.register(observer);
14314    }
14315
14316    @Override
14317    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14318        mUserSwitchObservers.unregister(observer);
14319    }
14320
14321    private boolean userExists(int userId) {
14322        if (userId == 0) {
14323            return true;
14324        }
14325        UserManagerService ums = getUserManagerLocked();
14326        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14327    }
14328
14329    int[] getUsersLocked() {
14330        UserManagerService ums = getUserManagerLocked();
14331        return ums != null ? ums.getUserIds() : new int[] { 0 };
14332    }
14333
14334    UserManagerService getUserManagerLocked() {
14335        if (mUserManager == null) {
14336            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14337            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14338        }
14339        return mUserManager;
14340    }
14341
14342    private void checkValidCaller(int uid, int userId) {
14343        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14344
14345        throw new SecurityException("Caller uid=" + uid
14346                + " is not privileged to communicate with user=" + userId);
14347    }
14348
14349    private int applyUserId(int uid, int userId) {
14350        return UserHandle.getUid(userId, uid);
14351    }
14352
14353    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14354        if (info == null) return null;
14355        ApplicationInfo newInfo = new ApplicationInfo(info);
14356        newInfo.uid = applyUserId(info.uid, userId);
14357        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14358                + info.packageName;
14359        return newInfo;
14360    }
14361
14362    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14363        if (aInfo == null
14364                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14365            return aInfo;
14366        }
14367
14368        ActivityInfo info = new ActivityInfo(aInfo);
14369        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14370        return info;
14371    }
14372}
14373