ActivityManagerService.java revision bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324
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.Arrays;
151import java.util.Collections;
152import java.util.Comparator;
153import java.util.HashMap;
154import java.util.HashSet;
155import java.util.Iterator;
156import java.util.List;
157import java.util.Locale;
158import java.util.Map;
159import java.util.Set;
160import java.util.concurrent.atomic.AtomicBoolean;
161import java.util.concurrent.atomic.AtomicLong;
162
163public final class ActivityManagerService extends ActivityManagerNative
164        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
165    private static final String USER_DATA_DIR = "/data/user/";
166    static final String TAG = "ActivityManager";
167    static final String TAG_MU = "ActivityManagerServiceMU";
168    static final boolean DEBUG = false;
169    static final boolean localLOGV = DEBUG;
170    static final boolean DEBUG_SWITCH = localLOGV || false;
171    static final boolean DEBUG_TASKS = localLOGV || false;
172    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
173    static final boolean DEBUG_PAUSE = localLOGV || false;
174    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
175    static final boolean DEBUG_TRANSITION = localLOGV || false;
176    static final boolean DEBUG_BROADCAST = localLOGV || false;
177    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
178    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_SERVICE = localLOGV || false;
180    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
181    static final boolean DEBUG_VISBILITY = localLOGV || false;
182    static final boolean DEBUG_PROCESSES = localLOGV || false;
183    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
184    static final boolean DEBUG_PROVIDER = localLOGV || false;
185    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
186    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
187    static final boolean DEBUG_RESULTS = localLOGV || false;
188    static final boolean DEBUG_BACKUP = localLOGV || false;
189    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
190    static final boolean DEBUG_POWER = localLOGV || false;
191    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
192    static final boolean DEBUG_MU = localLOGV || false;
193    static final boolean VALIDATE_TOKENS = false;
194    static final boolean SHOW_ACTIVITY_START_TIME = true;
195
196    // Control over CPU and battery monitoring.
197    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
198    static final boolean MONITOR_CPU_USAGE = true;
199    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
200    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
201    static final boolean MONITOR_THREAD_CPU_USAGE = false;
202
203    // The flags that are set for all calls we make to the package manager.
204    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
205
206    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
207
208    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
209
210    // Maximum number of recent tasks that we can remember.
211    static final int MAX_RECENT_TASKS = 20;
212
213    // Amount of time after a call to stopAppSwitches() during which we will
214    // prevent further untrusted switches from happening.
215    static final long APP_SWITCH_DELAY_TIME = 5*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real.
219    static final int PROC_START_TIMEOUT = 10*1000;
220
221    // How long we wait for a launched process to attach to the activity manager
222    // before we decide it's never going to come up for real, when the process was
223    // started with a wrapper for instrumentation (such as Valgrind) because it
224    // could take much longer than usual.
225    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
226
227    // How long to wait after going idle before forcing apps to GC.
228    static final int GC_TIMEOUT = 5*1000;
229
230    // The minimum amount of time between successive GC requests for a process.
231    static final int GC_MIN_INTERVAL = 60*1000;
232
233    // The rate at which we check for apps using excessive power -- 15 mins.
234    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on wake locks to start killing things.
238    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // The minimum sample duration we will allow before deciding we have
241    // enough data on CPU usage to start killing things.
242    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
243
244    // How long we allow a receiver to run before giving up on it.
245    static final int BROADCAST_FG_TIMEOUT = 10*1000;
246    static final int BROADCAST_BG_TIMEOUT = 60*1000;
247
248    // How long we wait until we timeout on key dispatching.
249    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
251    // How long we wait until we timeout on key dispatching during instrumentation.
252    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
254    // Amount of time we wait for observers to handle a user switch before
255    // giving up on them and unfreezing the screen.
256    static final int USER_SWITCH_TIMEOUT = 2*1000;
257
258    // Maximum number of users we allow to be running at a time.
259    static final int MAX_RUNNING_USERS = 3;
260
261    static final int MY_PID = Process.myPid();
262
263    static final String[] EMPTY_STRING_ARRAY = new String[0];
264
265    public ActivityStack mMainStack;
266
267    private final boolean mHeadless;
268
269    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
270    // default actuion automatically.  Important for devices without direct input
271    // devices.
272    private boolean mShowDialogs = true;
273
274    /**
275     * Description of a request to start a new activity, which has been held
276     * due to app switches being disabled.
277     */
278    static class PendingActivityLaunch {
279        ActivityRecord r;
280        ActivityRecord sourceRecord;
281        int startFlags;
282    }
283
284    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
285            = new ArrayList<PendingActivityLaunch>();
286
287
288    BroadcastQueue mFgBroadcastQueue;
289    BroadcastQueue mBgBroadcastQueue;
290    // Convenient for easy iteration over the queues. Foreground is first
291    // so that dispatch of foreground broadcasts gets precedence.
292    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
293
294    BroadcastQueue broadcastQueueForIntent(Intent intent) {
295        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
296        if (DEBUG_BACKGROUND_BROADCAST) {
297            Slog.i(TAG, "Broadcast intent " + intent + " on "
298                    + (isFg ? "foreground" : "background")
299                    + " queue");
300        }
301        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
302    }
303
304    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
305        for (BroadcastQueue queue : mBroadcastQueues) {
306            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
307            if (r != null) {
308                return r;
309            }
310        }
311        return null;
312    }
313
314    /**
315     * Activity we have told the window manager to have key focus.
316     */
317    ActivityRecord mFocusedActivity = null;
318    /**
319     * List of intents that were used to start the most recent tasks.
320     */
321    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
322
323    /**
324     * Process management.
325     */
326    final ProcessList mProcessList = new ProcessList();
327
328    /**
329     * All of the applications we currently have running organized by name.
330     * The keys are strings of the application package name (as
331     * returned by the package manager), and the keys are ApplicationRecord
332     * objects.
333     */
334    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
335
336    /**
337     * The currently running isolated processes.
338     */
339    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
340
341    /**
342     * Counter for assigning isolated process uids, to avoid frequently reusing the
343     * same ones.
344     */
345    int mNextIsolatedProcessUid = 0;
346
347    /**
348     * The currently running heavy-weight process, if any.
349     */
350    ProcessRecord mHeavyWeightProcess = null;
351
352    /**
353     * The last time that various processes have crashed.
354     */
355    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
356
357    /**
358     * Set of applications that we consider to be bad, and will reject
359     * incoming broadcasts from (which the user has no control over).
360     * Processes are added to this set when they have crashed twice within
361     * a minimum amount of time; they are removed from it when they are
362     * later restarted (hopefully due to some user action).  The value is the
363     * time it was added to the list.
364     */
365    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
366
367    /**
368     * All of the processes we currently have running organized by pid.
369     * The keys are the pid running the application.
370     *
371     * <p>NOTE: This object is protected by its own lock, NOT the global
372     * activity manager lock!
373     */
374    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
375
376    /**
377     * All of the processes that have been forced to be foreground.  The key
378     * is the pid of the caller who requested it (we hold a death
379     * link on it).
380     */
381    abstract class ForegroundToken implements IBinder.DeathRecipient {
382        int pid;
383        IBinder token;
384    }
385    final SparseArray<ForegroundToken> mForegroundProcesses
386            = new SparseArray<ForegroundToken>();
387
388    /**
389     * List of records for processes that someone had tried to start before the
390     * system was ready.  We don't start them at that point, but ensure they
391     * are started by the time booting is complete.
392     */
393    final ArrayList<ProcessRecord> mProcessesOnHold
394            = new ArrayList<ProcessRecord>();
395
396    /**
397     * List of persistent applications that are in the process
398     * of being started.
399     */
400    final ArrayList<ProcessRecord> mPersistentStartingProcesses
401            = new ArrayList<ProcessRecord>();
402
403    /**
404     * Processes that are being forcibly torn down.
405     */
406    final ArrayList<ProcessRecord> mRemovedProcesses
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * List of running applications, sorted by recent usage.
411     * The first entry in the list is the least recently used.
412     * It contains ApplicationRecord objects.  This list does NOT include
413     * any persistent application records (since we never want to exit them).
414     */
415    final ArrayList<ProcessRecord> mLruProcesses
416            = new ArrayList<ProcessRecord>();
417
418    /**
419     * List of processes that should gc as soon as things are idle.
420     */
421    final ArrayList<ProcessRecord> mProcessesToGc
422            = new ArrayList<ProcessRecord>();
423
424    /**
425     * This is the process holding what we currently consider to be
426     * the "home" activity.
427     */
428    ProcessRecord mHomeProcess;
429
430    /**
431     * This is the process holding the activity the user last visited that
432     * is in a different process from the one they are currently in.
433     */
434    ProcessRecord mPreviousProcess;
435
436    /**
437     * The time at which the previous process was last visible.
438     */
439    long mPreviousProcessVisibleTime;
440
441    /**
442     * Which uses have been started, so are allowed to run code.
443     */
444    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
445
446    /**
447     * LRU list of history of current users.  Most recently current is at the end.
448     */
449    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
450
451    /**
452     * Constant array of the users that are currently started.
453     */
454    int[] mStartedUserArray = new int[] { 0 };
455
456    /**
457     * Registered observers of the user switching mechanics.
458     */
459    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
460            = new RemoteCallbackList<IUserSwitchObserver>();
461
462    /**
463     * Currently active user switch.
464     */
465    Object mCurUserSwitchCallback;
466
467    /**
468     * Packages that the user has asked to have run in screen size
469     * compatibility mode instead of filling the screen.
470     */
471    final CompatModePackages mCompatModePackages;
472
473    /**
474     * Set of PendingResultRecord objects that are currently active.
475     */
476    final HashSet mPendingResultRecords = new HashSet();
477
478    /**
479     * Set of IntentSenderRecord objects that are currently active.
480     */
481    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
482            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
483
484    /**
485     * Fingerprints (hashCode()) of stack traces that we've
486     * already logged DropBox entries for.  Guarded by itself.  If
487     * something (rogue user app) forces this over
488     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
489     */
490    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
491    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
492
493    /**
494     * Strict Mode background batched logging state.
495     *
496     * The string buffer is guarded by itself, and its lock is also
497     * used to determine if another batched write is already
498     * in-flight.
499     */
500    private final StringBuilder mStrictModeBuffer = new StringBuilder();
501
502    /**
503     * Keeps track of all IIntentReceivers that have been registered for
504     * broadcasts.  Hash keys are the receiver IBinder, hash value is
505     * a ReceiverList.
506     */
507    final HashMap mRegisteredReceivers = new HashMap();
508
509    /**
510     * Resolver for broadcast intents to registered receivers.
511     * Holds BroadcastFilter (subclass of IntentFilter).
512     */
513    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
514            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
515        @Override
516        protected boolean allowFilterResult(
517                BroadcastFilter filter, List<BroadcastFilter> dest) {
518            IBinder target = filter.receiverList.receiver.asBinder();
519            for (int i=dest.size()-1; i>=0; i--) {
520                if (dest.get(i).receiverList.receiver.asBinder() == target) {
521                    return false;
522                }
523            }
524            return true;
525        }
526
527        @Override
528        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
529            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
530                    || userId == filter.owningUserId) {
531                return super.newResult(filter, match, userId);
532            }
533            return null;
534        }
535
536        @Override
537        protected BroadcastFilter[] newArray(int size) {
538            return new BroadcastFilter[size];
539        }
540
541        @Override
542        protected String packageForFilter(BroadcastFilter filter) {
543            return filter.packageName;
544        }
545    };
546
547    /**
548     * State of all active sticky broadcasts per user.  Keys are the action of the
549     * sticky Intent, values are an ArrayList of all broadcasted intents with
550     * that action (which should usually be one).  The SparseArray is keyed
551     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
552     * for stickies that are sent to all users.
553     */
554    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
555            new SparseArray<HashMap<String, ArrayList<Intent>>>();
556
557    final ActiveServices mServices;
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    final ProviderMap mProviderMap;
578
579    /**
580     * List of content providers who have clients waiting for them.  The
581     * application is currently being launched and the provider will be
582     * removed from this list once it is published.
583     */
584    final ArrayList<ContentProviderRecord> mLaunchingProviders
585            = new ArrayList<ContentProviderRecord>();
586
587    /**
588     * Global set of specific Uri permissions that have been granted.
589     */
590    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591            = new SparseArray<HashMap<Uri, UriPermission>>();
592
593    CoreSettingsObserver mCoreSettingsObserver;
594
595    /**
596     * Thread-local storage used to carry caller permissions over through
597     * indirect content-provider access.
598     * @see #ActivityManagerService.openContentUri()
599     */
600    private class Identity {
601        public int pid;
602        public int uid;
603
604        Identity(int _pid, int _uid) {
605            pid = _pid;
606            uid = _uid;
607        }
608    }
609
610    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
611
612    /**
613     * All information we have collected about the runtime performance of
614     * any user id that can impact battery performance.
615     */
616    final BatteryStatsService mBatteryStatsService;
617
618    /**
619     * information about component usage
620     */
621    final UsageStatsService mUsageStatsService;
622
623    /**
624     * Current configuration information.  HistoryRecord objects are given
625     * a reference to this object to indicate which configuration they are
626     * currently running in, so this object must be kept immutable.
627     */
628    Configuration mConfiguration = new Configuration();
629
630    /**
631     * Current sequencing integer of the configuration, for skipping old
632     * configurations.
633     */
634    int mConfigurationSeq = 0;
635
636    /**
637     * Hardware-reported OpenGLES version.
638     */
639    final int GL_ES_VERSION;
640
641    /**
642     * List of initialization arguments to pass to all processes when binding applications to them.
643     * For example, references to the commonly used services.
644     */
645    HashMap<String, IBinder> mAppBindArgs;
646
647    /**
648     * Temporary to avoid allocations.  Protected by main lock.
649     */
650    final StringBuilder mStringBuilder = new StringBuilder(256);
651
652    /**
653     * Used to control how we initialize the service.
654     */
655    boolean mStartRunning = false;
656    ComponentName mTopComponent;
657    String mTopAction;
658    String mTopData;
659    boolean mProcessesReady = false;
660    boolean mSystemReady = false;
661    boolean mBooting = false;
662    boolean mWaitingUpdate = false;
663    boolean mDidUpdate = false;
664    boolean mOnBattery = false;
665    boolean mLaunchWarningShown = false;
666
667    Context mContext;
668
669    int mFactoryTest;
670
671    boolean mCheckedForSetup;
672
673    /**
674     * The time at which we will allow normal application switches again,
675     * after a call to {@link #stopAppSwitches()}.
676     */
677    long mAppSwitchesAllowedTime;
678
679    /**
680     * This is set to true after the first switch after mAppSwitchesAllowedTime
681     * is set; any switches after that will clear the time.
682     */
683    boolean mDidAppSwitch;
684
685    /**
686     * Last time (in realtime) at which we checked for power usage.
687     */
688    long mLastPowerCheckRealtime;
689
690    /**
691     * Last time (in uptime) at which we checked for power usage.
692     */
693    long mLastPowerCheckUptime;
694
695    /**
696     * Set while we are wanting to sleep, to prevent any
697     * activities from being started/resumed.
698     */
699    boolean mSleeping = false;
700
701    /**
702     * State of external calls telling us if the device is asleep.
703     */
704    boolean mWentToSleep = false;
705
706    /**
707     * State of external call telling us if the lock screen is shown.
708     */
709    boolean mLockScreenShown = false;
710
711    /**
712     * Set if we are shutting down the system, similar to sleeping.
713     */
714    boolean mShuttingDown = false;
715
716    /**
717     * Task identifier that activities are currently being started
718     * in.  Incremented each time a new task is created.
719     * todo: Replace this with a TokenSpace class that generates non-repeating
720     * integers that won't wrap.
721     */
722    int mCurTask = 1;
723
724    /**
725     * Current sequence id for oom_adj computation traversal.
726     */
727    int mAdjSeq = 0;
728
729    /**
730     * Current sequence id for process LRU updating.
731     */
732    int mLruSeq = 0;
733
734    /**
735     * Keep track of the non-hidden/empty process we last found, to help
736     * determine how to distribute hidden/empty processes next time.
737     */
738    int mNumNonHiddenProcs = 0;
739
740    /**
741     * Keep track of the number of hidden procs, to balance oom adj
742     * distribution between those and empty procs.
743     */
744    int mNumHiddenProcs = 0;
745
746    /**
747     * Keep track of the number of service processes we last found, to
748     * determine on the next iteration which should be B services.
749     */
750    int mNumServiceProcs = 0;
751    int mNewNumServiceProcs = 0;
752
753    /**
754     * System monitoring: number of processes that died since the last
755     * N procs were started.
756     */
757    int[] mProcDeaths = new int[20];
758
759    /**
760     * This is set if we had to do a delayed dexopt of an app before launching
761     * it, to increasing the ANR timeouts in that case.
762     */
763    boolean mDidDexOpt;
764
765    String mDebugApp = null;
766    boolean mWaitForDebugger = false;
767    boolean mDebugTransient = false;
768    String mOrigDebugApp = null;
769    boolean mOrigWaitForDebugger = false;
770    boolean mAlwaysFinishActivities = false;
771    IActivityController mController = null;
772    String mProfileApp = null;
773    ProcessRecord mProfileProc = null;
774    String mProfileFile;
775    ParcelFileDescriptor mProfileFd;
776    int mProfileType = 0;
777    boolean mAutoStopProfiler = false;
778    String mOpenGlTraceApp = null;
779
780    static class ProcessChangeItem {
781        static final int CHANGE_ACTIVITIES = 1<<0;
782        static final int CHANGE_IMPORTANCE= 1<<1;
783        int changes;
784        int uid;
785        int pid;
786        int importance;
787        boolean foregroundActivities;
788    }
789
790    final RemoteCallbackList<IProcessObserver> mProcessObservers
791            = new RemoteCallbackList<IProcessObserver>();
792    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
793
794    final ArrayList<ProcessChangeItem> mPendingProcessChanges
795            = new ArrayList<ProcessChangeItem>();
796    final ArrayList<ProcessChangeItem> mAvailProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798
799    /**
800     * Callback of last caller to {@link #requestPss}.
801     */
802    Runnable mRequestPssCallback;
803
804    /**
805     * Remaining processes for which we are waiting results from the last
806     * call to {@link #requestPss}.
807     */
808    final ArrayList<ProcessRecord> mRequestPssList
809            = new ArrayList<ProcessRecord>();
810
811    /**
812     * Runtime statistics collection thread.  This object's lock is used to
813     * protect all related state.
814     */
815    final Thread mProcessStatsThread;
816
817    /**
818     * Used to collect process stats when showing not responding dialog.
819     * Protected by mProcessStatsThread.
820     */
821    final ProcessStats mProcessStats = new ProcessStats(
822            MONITOR_THREAD_CPU_USAGE);
823    final AtomicLong mLastCpuTime = new AtomicLong(0);
824    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
825
826    long mLastWriteTime = 0;
827
828    /**
829     * Set to true after the system has finished booting.
830     */
831    boolean mBooted = false;
832
833    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
834    int mProcessLimitOverride = -1;
835
836    WindowManagerService mWindowManager;
837
838    static ActivityManagerService mSelf;
839    static ActivityThread mSystemThread;
840
841    private int mCurrentUserId = 0;
842    private int[] mCurrentUserArray = new int[] { 0 };
843    private UserManagerService mUserManager;
844
845    private final class AppDeathRecipient implements IBinder.DeathRecipient {
846        final ProcessRecord mApp;
847        final int mPid;
848        final IApplicationThread mAppThread;
849
850        AppDeathRecipient(ProcessRecord app, int pid,
851                IApplicationThread thread) {
852            if (localLOGV) Slog.v(
853                TAG, "New death recipient " + this
854                + " for thread " + thread.asBinder());
855            mApp = app;
856            mPid = pid;
857            mAppThread = thread;
858        }
859
860        public void binderDied() {
861            if (localLOGV) Slog.v(
862                TAG, "Death received in " + this
863                + " for thread " + mAppThread.asBinder());
864            synchronized(ActivityManagerService.this) {
865                appDiedLocked(mApp, mPid, mAppThread);
866            }
867        }
868    }
869
870    static final int SHOW_ERROR_MSG = 1;
871    static final int SHOW_NOT_RESPONDING_MSG = 2;
872    static final int SHOW_FACTORY_ERROR_MSG = 3;
873    static final int UPDATE_CONFIGURATION_MSG = 4;
874    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
875    static final int WAIT_FOR_DEBUGGER_MSG = 6;
876    static final int SERVICE_TIMEOUT_MSG = 12;
877    static final int UPDATE_TIME_ZONE = 13;
878    static final int SHOW_UID_ERROR_MSG = 14;
879    static final int IM_FEELING_LUCKY_MSG = 15;
880    static final int PROC_START_TIMEOUT_MSG = 20;
881    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
882    static final int KILL_APPLICATION_MSG = 22;
883    static final int FINALIZE_PENDING_INTENT_MSG = 23;
884    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
885    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
886    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
887    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
888    static final int CLEAR_DNS_CACHE = 28;
889    static final int UPDATE_HTTP_PROXY = 29;
890    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
891    static final int DISPATCH_PROCESSES_CHANGED = 31;
892    static final int DISPATCH_PROCESS_DIED = 32;
893    static final int REPORT_MEM_USAGE = 33;
894    static final int REPORT_USER_SWITCH_MSG = 34;
895    static final int CONTINUE_USER_SWITCH_MSG = 35;
896    static final int USER_SWITCH_TIMEOUT_MSG = 36;
897
898    static final int FIRST_ACTIVITY_STACK_MSG = 100;
899    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
900    static final int FIRST_COMPAT_MODE_MSG = 300;
901
902    AlertDialog mUidAlert;
903    CompatModeDialog mCompatModeDialog;
904    long mLastMemUsageReportTime = 0;
905
906    final Handler mHandler = new Handler() {
907        //public Handler() {
908        //    if (localLOGV) Slog.v(TAG, "Handler started!");
909        //}
910
911        public void handleMessage(Message msg) {
912            switch (msg.what) {
913            case SHOW_ERROR_MSG: {
914                HashMap data = (HashMap) msg.obj;
915                synchronized (ActivityManagerService.this) {
916                    ProcessRecord proc = (ProcessRecord)data.get("app");
917                    if (proc != null && proc.crashDialog != null) {
918                        Slog.e(TAG, "App already has crash dialog: " + proc);
919                        return;
920                    }
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
923                        Dialog d = new AppErrorDialog(mContext, res, proc);
924                        d.show();
925                        proc.crashDialog = d;
926                    } else {
927                        // The device is asleep, so just pretend that the user
928                        // saw a crash dialog and hit "force quit".
929                        res.set(0);
930                    }
931                }
932
933                ensureBootCompleted();
934            } break;
935            case SHOW_NOT_RESPONDING_MSG: {
936                synchronized (ActivityManagerService.this) {
937                    HashMap data = (HashMap) msg.obj;
938                    ProcessRecord proc = (ProcessRecord)data.get("app");
939                    if (proc != null && proc.anrDialog != null) {
940                        Slog.e(TAG, "App already has anr dialog: " + proc);
941                        return;
942                    }
943
944                    Intent intent = new Intent("android.intent.action.ANR");
945                    if (!mProcessesReady) {
946                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
947                                | Intent.FLAG_RECEIVER_FOREGROUND);
948                    }
949                    broadcastIntentLocked(null, null, intent,
950                            null, null, 0, null, null, null,
951                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
952
953                    if (mShowDialogs) {
954                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
955                                mContext, proc, (ActivityRecord)data.get("activity"));
956                        d.show();
957                        proc.anrDialog = d;
958                    } else {
959                        // Just kill the app if there is no dialog to be shown.
960                        killAppAtUsersRequest(proc, null);
961                    }
962                }
963
964                ensureBootCompleted();
965            } break;
966            case SHOW_STRICT_MODE_VIOLATION_MSG: {
967                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
968                synchronized (ActivityManagerService.this) {
969                    ProcessRecord proc = (ProcessRecord) data.get("app");
970                    if (proc == null) {
971                        Slog.e(TAG, "App not found when showing strict mode dialog.");
972                        break;
973                    }
974                    if (proc.crashDialog != null) {
975                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
976                        return;
977                    }
978                    AppErrorResult res = (AppErrorResult) data.get("result");
979                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
980                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
981                        d.show();
982                        proc.crashDialog = d;
983                    } else {
984                        // The device is asleep, so just pretend that the user
985                        // saw a crash dialog and hit "force quit".
986                        res.set(0);
987                    }
988                }
989                ensureBootCompleted();
990            } break;
991            case SHOW_FACTORY_ERROR_MSG: {
992                Dialog d = new FactoryErrorDialog(
993                    mContext, msg.getData().getCharSequence("msg"));
994                d.show();
995                ensureBootCompleted();
996            } break;
997            case UPDATE_CONFIGURATION_MSG: {
998                final ContentResolver resolver = mContext.getContentResolver();
999                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1000            } break;
1001            case GC_BACKGROUND_PROCESSES_MSG: {
1002                synchronized (ActivityManagerService.this) {
1003                    performAppGcsIfAppropriateLocked();
1004                }
1005            } break;
1006            case WAIT_FOR_DEBUGGER_MSG: {
1007                synchronized (ActivityManagerService.this) {
1008                    ProcessRecord app = (ProcessRecord)msg.obj;
1009                    if (msg.arg1 != 0) {
1010                        if (!app.waitedForDebugger) {
1011                            Dialog d = new AppWaitingForDebuggerDialog(
1012                                    ActivityManagerService.this,
1013                                    mContext, app);
1014                            app.waitDialog = d;
1015                            app.waitedForDebugger = true;
1016                            d.show();
1017                        }
1018                    } else {
1019                        if (app.waitDialog != null) {
1020                            app.waitDialog.dismiss();
1021                            app.waitDialog = null;
1022                        }
1023                    }
1024                }
1025            } break;
1026            case SERVICE_TIMEOUT_MSG: {
1027                if (mDidDexOpt) {
1028                    mDidDexOpt = false;
1029                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1030                    nmsg.obj = msg.obj;
1031                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1032                    return;
1033                }
1034                mServices.serviceTimeout((ProcessRecord)msg.obj);
1035            } break;
1036            case UPDATE_TIME_ZONE: {
1037                synchronized (ActivityManagerService.this) {
1038                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1039                        ProcessRecord r = mLruProcesses.get(i);
1040                        if (r.thread != null) {
1041                            try {
1042                                r.thread.updateTimeZone();
1043                            } catch (RemoteException ex) {
1044                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1045                            }
1046                        }
1047                    }
1048                }
1049            } break;
1050            case CLEAR_DNS_CACHE: {
1051                synchronized (ActivityManagerService.this) {
1052                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1053                        ProcessRecord r = mLruProcesses.get(i);
1054                        if (r.thread != null) {
1055                            try {
1056                                r.thread.clearDnsCache();
1057                            } catch (RemoteException ex) {
1058                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1059                            }
1060                        }
1061                    }
1062                }
1063            } break;
1064            case UPDATE_HTTP_PROXY: {
1065                ProxyProperties proxy = (ProxyProperties)msg.obj;
1066                String host = "";
1067                String port = "";
1068                String exclList = "";
1069                if (proxy != null) {
1070                    host = proxy.getHost();
1071                    port = Integer.toString(proxy.getPort());
1072                    exclList = proxy.getExclusionList();
1073                }
1074                synchronized (ActivityManagerService.this) {
1075                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1076                        ProcessRecord r = mLruProcesses.get(i);
1077                        if (r.thread != null) {
1078                            try {
1079                                r.thread.setHttpProxy(host, port, exclList);
1080                            } catch (RemoteException ex) {
1081                                Slog.w(TAG, "Failed to update http proxy for: " +
1082                                        r.info.processName);
1083                            }
1084                        }
1085                    }
1086                }
1087            } break;
1088            case SHOW_UID_ERROR_MSG: {
1089                String title = "System UIDs Inconsistent";
1090                String text = "UIDs on the system are inconsistent, you need to wipe your"
1091                        + " data partition or your device will be unstable.";
1092                Log.e(TAG, title + ": " + text);
1093                if (mShowDialogs) {
1094                    // XXX This is a temporary dialog, no need to localize.
1095                    AlertDialog d = new BaseErrorDialog(mContext);
1096                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1097                    d.setCancelable(false);
1098                    d.setTitle(title);
1099                    d.setMessage(text);
1100                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1101                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1102                    mUidAlert = d;
1103                    d.show();
1104                }
1105            } break;
1106            case IM_FEELING_LUCKY_MSG: {
1107                if (mUidAlert != null) {
1108                    mUidAlert.dismiss();
1109                    mUidAlert = null;
1110                }
1111            } break;
1112            case PROC_START_TIMEOUT_MSG: {
1113                if (mDidDexOpt) {
1114                    mDidDexOpt = false;
1115                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1116                    nmsg.obj = msg.obj;
1117                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1118                    return;
1119                }
1120                ProcessRecord app = (ProcessRecord)msg.obj;
1121                synchronized (ActivityManagerService.this) {
1122                    processStartTimedOutLocked(app);
1123                }
1124            } break;
1125            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1126                synchronized (ActivityManagerService.this) {
1127                    doPendingActivityLaunchesLocked(true);
1128                }
1129            } break;
1130            case KILL_APPLICATION_MSG: {
1131                synchronized (ActivityManagerService.this) {
1132                    int appid = msg.arg1;
1133                    boolean restart = (msg.arg2 == 1);
1134                    String pkg = (String) msg.obj;
1135                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1136                            UserHandle.USER_ALL);
1137                }
1138            } break;
1139            case FINALIZE_PENDING_INTENT_MSG: {
1140                ((PendingIntentRecord)msg.obj).completeFinalize();
1141            } break;
1142            case POST_HEAVY_NOTIFICATION_MSG: {
1143                INotificationManager inm = NotificationManager.getService();
1144                if (inm == null) {
1145                    return;
1146                }
1147
1148                ActivityRecord root = (ActivityRecord)msg.obj;
1149                ProcessRecord process = root.app;
1150                if (process == null) {
1151                    return;
1152                }
1153
1154                try {
1155                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1156                    String text = mContext.getString(R.string.heavy_weight_notification,
1157                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1158                    Notification notification = new Notification();
1159                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1160                    notification.when = 0;
1161                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1162                    notification.tickerText = text;
1163                    notification.defaults = 0; // please be quiet
1164                    notification.sound = null;
1165                    notification.vibrate = null;
1166                    notification.setLatestEventInfo(context, text,
1167                            mContext.getText(R.string.heavy_weight_notification_detail),
1168                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1169                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1170                                    new UserHandle(root.userId)));
1171
1172                    try {
1173                        int[] outId = new int[1];
1174                        inm.enqueueNotificationWithTag("android", null,
1175                                R.string.heavy_weight_notification,
1176                                notification, outId, root.userId);
1177                    } catch (RuntimeException e) {
1178                        Slog.w(ActivityManagerService.TAG,
1179                                "Error showing notification for heavy-weight app", e);
1180                    } catch (RemoteException e) {
1181                    }
1182                } catch (NameNotFoundException e) {
1183                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1184                }
1185            } break;
1186            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1187                INotificationManager inm = NotificationManager.getService();
1188                if (inm == null) {
1189                    return;
1190                }
1191                try {
1192                    inm.cancelNotificationWithTag("android", null,
1193                            R.string.heavy_weight_notification,  msg.arg1);
1194                } catch (RuntimeException e) {
1195                    Slog.w(ActivityManagerService.TAG,
1196                            "Error canceling notification for service", e);
1197                } catch (RemoteException e) {
1198                }
1199            } break;
1200            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    checkExcessivePowerUsageLocked(true);
1203                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1204                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1205                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1206                }
1207            } break;
1208            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1209                synchronized (ActivityManagerService.this) {
1210                    ActivityRecord ar = (ActivityRecord)msg.obj;
1211                    if (mCompatModeDialog != null) {
1212                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1213                                ar.info.applicationInfo.packageName)) {
1214                            return;
1215                        }
1216                        mCompatModeDialog.dismiss();
1217                        mCompatModeDialog = null;
1218                    }
1219                    if (ar != null && false) {
1220                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1221                                ar.packageName)) {
1222                            int mode = mCompatModePackages.computeCompatModeLocked(
1223                                    ar.info.applicationInfo);
1224                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1225                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1226                                mCompatModeDialog = new CompatModeDialog(
1227                                        ActivityManagerService.this, mContext,
1228                                        ar.info.applicationInfo);
1229                                mCompatModeDialog.show();
1230                            }
1231                        }
1232                    }
1233                }
1234                break;
1235            }
1236            case DISPATCH_PROCESSES_CHANGED: {
1237                dispatchProcessesChanged();
1238                break;
1239            }
1240            case DISPATCH_PROCESS_DIED: {
1241                final int pid = msg.arg1;
1242                final int uid = msg.arg2;
1243                dispatchProcessDied(pid, uid);
1244                break;
1245            }
1246            case REPORT_MEM_USAGE: {
1247                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1248                if (!isDebuggable) {
1249                    return;
1250                }
1251                synchronized (ActivityManagerService.this) {
1252                    long now = SystemClock.uptimeMillis();
1253                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1254                        // Don't report more than every 5 minutes to somewhat
1255                        // avoid spamming.
1256                        return;
1257                    }
1258                    mLastMemUsageReportTime = now;
1259                }
1260                Thread thread = new Thread() {
1261                    @Override public void run() {
1262                        StringBuilder dropBuilder = new StringBuilder(1024);
1263                        StringBuilder logBuilder = new StringBuilder(1024);
1264                        StringWriter oomSw = new StringWriter();
1265                        PrintWriter oomPw = new PrintWriter(oomSw);
1266                        StringWriter catSw = new StringWriter();
1267                        PrintWriter catPw = new PrintWriter(catSw);
1268                        String[] emptyArgs = new String[] { };
1269                        StringBuilder tag = new StringBuilder(128);
1270                        StringBuilder stack = new StringBuilder(128);
1271                        tag.append("Low on memory -- ");
1272                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1273                                tag, stack);
1274                        dropBuilder.append(stack);
1275                        dropBuilder.append('\n');
1276                        dropBuilder.append('\n');
1277                        String oomString = oomSw.toString();
1278                        dropBuilder.append(oomString);
1279                        dropBuilder.append('\n');
1280                        logBuilder.append(oomString);
1281                        try {
1282                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1283                                    "procrank", });
1284                            final InputStreamReader converter = new InputStreamReader(
1285                                    proc.getInputStream());
1286                            BufferedReader in = new BufferedReader(converter);
1287                            String line;
1288                            while (true) {
1289                                line = in.readLine();
1290                                if (line == null) {
1291                                    break;
1292                                }
1293                                if (line.length() > 0) {
1294                                    logBuilder.append(line);
1295                                    logBuilder.append('\n');
1296                                }
1297                                dropBuilder.append(line);
1298                                dropBuilder.append('\n');
1299                            }
1300                            converter.close();
1301                        } catch (IOException e) {
1302                        }
1303                        synchronized (ActivityManagerService.this) {
1304                            catPw.println();
1305                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1306                            catPw.println();
1307                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1308                                    false, false, null);
1309                            catPw.println();
1310                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1311                        }
1312                        dropBuilder.append(catSw.toString());
1313                        addErrorToDropBox("lowmem", null, "system_server", null,
1314                                null, tag.toString(), dropBuilder.toString(), null, null);
1315                        Slog.i(TAG, logBuilder.toString());
1316                        synchronized (ActivityManagerService.this) {
1317                            long now = SystemClock.uptimeMillis();
1318                            if (mLastMemUsageReportTime < now) {
1319                                mLastMemUsageReportTime = now;
1320                            }
1321                        }
1322                    }
1323                };
1324                thread.start();
1325                break;
1326            }
1327            case REPORT_USER_SWITCH_MSG: {
1328                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1329                break;
1330            }
1331            case CONTINUE_USER_SWITCH_MSG: {
1332                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1333                break;
1334            }
1335            case USER_SWITCH_TIMEOUT_MSG: {
1336                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1337                break;
1338            }
1339            }
1340        }
1341    };
1342
1343    public static void setSystemProcess() {
1344        try {
1345            ActivityManagerService m = mSelf;
1346
1347            ServiceManager.addService("activity", m, true);
1348            ServiceManager.addService("meminfo", new MemBinder(m));
1349            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1350            ServiceManager.addService("dbinfo", new DbBinder(m));
1351            if (MONITOR_CPU_USAGE) {
1352                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1353            }
1354            ServiceManager.addService("permission", new PermissionController(m));
1355
1356            ApplicationInfo info =
1357                mSelf.mContext.getPackageManager().getApplicationInfo(
1358                            "android", STOCK_PM_FLAGS);
1359            mSystemThread.installSystemApplicationInfo(info);
1360
1361            synchronized (mSelf) {
1362                ProcessRecord app = mSelf.newProcessRecordLocked(
1363                        mSystemThread.getApplicationThread(), info,
1364                        info.processName, false);
1365                app.persistent = true;
1366                app.pid = MY_PID;
1367                app.maxAdj = ProcessList.SYSTEM_ADJ;
1368                mSelf.mProcessNames.put(app.processName, app.uid, app);
1369                synchronized (mSelf.mPidsSelfLocked) {
1370                    mSelf.mPidsSelfLocked.put(app.pid, app);
1371                }
1372                mSelf.updateLruProcessLocked(app, true, true);
1373            }
1374        } catch (PackageManager.NameNotFoundException e) {
1375            throw new RuntimeException(
1376                    "Unable to find android system package", e);
1377        }
1378    }
1379
1380    public void setWindowManager(WindowManagerService wm) {
1381        mWindowManager = wm;
1382    }
1383
1384    public static final Context main(int factoryTest) {
1385        AThread thr = new AThread();
1386        thr.start();
1387
1388        synchronized (thr) {
1389            while (thr.mService == null) {
1390                try {
1391                    thr.wait();
1392                } catch (InterruptedException e) {
1393                }
1394            }
1395        }
1396
1397        ActivityManagerService m = thr.mService;
1398        mSelf = m;
1399        ActivityThread at = ActivityThread.systemMain();
1400        mSystemThread = at;
1401        Context context = at.getSystemContext();
1402        context.setTheme(android.R.style.Theme_Holo);
1403        m.mContext = context;
1404        m.mFactoryTest = factoryTest;
1405        m.mMainStack = new ActivityStack(m, context, true);
1406
1407        m.mBatteryStatsService.publish(context);
1408        m.mUsageStatsService.publish(context);
1409
1410        synchronized (thr) {
1411            thr.mReady = true;
1412            thr.notifyAll();
1413        }
1414
1415        m.startRunning(null, null, null, null);
1416
1417        return context;
1418    }
1419
1420    public static ActivityManagerService self() {
1421        return mSelf;
1422    }
1423
1424    static class AThread extends Thread {
1425        ActivityManagerService mService;
1426        boolean mReady = false;
1427
1428        public AThread() {
1429            super("ActivityManager");
1430        }
1431
1432        public void run() {
1433            Looper.prepare();
1434
1435            android.os.Process.setThreadPriority(
1436                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1437            android.os.Process.setCanSelfBackground(false);
1438
1439            ActivityManagerService m = new ActivityManagerService();
1440
1441            synchronized (this) {
1442                mService = m;
1443                notifyAll();
1444            }
1445
1446            synchronized (this) {
1447                while (!mReady) {
1448                    try {
1449                        wait();
1450                    } catch (InterruptedException e) {
1451                    }
1452                }
1453            }
1454
1455            // For debug builds, log event loop stalls to dropbox for analysis.
1456            if (StrictMode.conditionallyEnableDebugLogging()) {
1457                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1458            }
1459
1460            Looper.loop();
1461        }
1462    }
1463
1464    static class MemBinder extends Binder {
1465        ActivityManagerService mActivityManagerService;
1466        MemBinder(ActivityManagerService activityManagerService) {
1467            mActivityManagerService = activityManagerService;
1468        }
1469
1470        @Override
1471        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1472            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1473                    != PackageManager.PERMISSION_GRANTED) {
1474                pw.println("Permission Denial: can't dump meminfo from from pid="
1475                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1476                        + " without permission " + android.Manifest.permission.DUMP);
1477                return;
1478            }
1479
1480            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1481                    false, null, null, null);
1482        }
1483    }
1484
1485    static class GraphicsBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        GraphicsBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1502        }
1503    }
1504
1505    static class DbBinder extends Binder {
1506        ActivityManagerService mActivityManagerService;
1507        DbBinder(ActivityManagerService activityManagerService) {
1508            mActivityManagerService = activityManagerService;
1509        }
1510
1511        @Override
1512        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1513            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1514                    != PackageManager.PERMISSION_GRANTED) {
1515                pw.println("Permission Denial: can't dump dbinfo from from pid="
1516                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1517                        + " without permission " + android.Manifest.permission.DUMP);
1518                return;
1519            }
1520
1521            mActivityManagerService.dumpDbInfo(fd, pw, args);
1522        }
1523    }
1524
1525    static class CpuBinder extends Binder {
1526        ActivityManagerService mActivityManagerService;
1527        CpuBinder(ActivityManagerService activityManagerService) {
1528            mActivityManagerService = activityManagerService;
1529        }
1530
1531        @Override
1532        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1533            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1534                    != PackageManager.PERMISSION_GRANTED) {
1535                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1536                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1537                        + " without permission " + android.Manifest.permission.DUMP);
1538                return;
1539            }
1540
1541            synchronized (mActivityManagerService.mProcessStatsThread) {
1542                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1543                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1544                        SystemClock.uptimeMillis()));
1545            }
1546        }
1547    }
1548
1549    private ActivityManagerService() {
1550        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1551
1552        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1553        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1554        mBroadcastQueues[0] = mFgBroadcastQueue;
1555        mBroadcastQueues[1] = mBgBroadcastQueue;
1556
1557        mServices = new ActiveServices(this);
1558        mProviderMap = new ProviderMap(this);
1559
1560        File dataDir = Environment.getDataDirectory();
1561        File systemDir = new File(dataDir, "system");
1562        systemDir.mkdirs();
1563        mBatteryStatsService = new BatteryStatsService(new File(
1564                systemDir, "batterystats.bin").toString());
1565        mBatteryStatsService.getActiveStatistics().readLocked();
1566        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1567        mOnBattery = DEBUG_POWER ? true
1568                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1569        mBatteryStatsService.getActiveStatistics().setCallback(this);
1570
1571        mUsageStatsService = new UsageStatsService(new File(
1572                systemDir, "usagestats").toString());
1573        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1574
1575        // User 0 is the first and only user that runs at boot.
1576        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1577        mUserLru.add(Integer.valueOf(0));
1578        updateStartedUserArrayLocked();
1579
1580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1582
1583        mConfiguration.setToDefaults();
1584        mConfiguration.setLocale(Locale.getDefault());
1585
1586        mConfigurationSeq = mConfiguration.seq = 1;
1587        mProcessStats.init();
1588
1589        mCompatModePackages = new CompatModePackages(this, systemDir);
1590
1591        // Add ourself to the Watchdog monitors.
1592        Watchdog.getInstance().addMonitor(this);
1593
1594        mProcessStatsThread = new Thread("ProcessStats") {
1595            public void run() {
1596                while (true) {
1597                    try {
1598                        try {
1599                            synchronized(this) {
1600                                final long now = SystemClock.uptimeMillis();
1601                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1602                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1603                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1604                                //        + ", write delay=" + nextWriteDelay);
1605                                if (nextWriteDelay < nextCpuDelay) {
1606                                    nextCpuDelay = nextWriteDelay;
1607                                }
1608                                if (nextCpuDelay > 0) {
1609                                    mProcessStatsMutexFree.set(true);
1610                                    this.wait(nextCpuDelay);
1611                                }
1612                            }
1613                        } catch (InterruptedException e) {
1614                        }
1615                        updateCpuStatsNow();
1616                    } catch (Exception e) {
1617                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1618                    }
1619                }
1620            }
1621        };
1622        mProcessStatsThread.start();
1623    }
1624
1625    @Override
1626    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1627            throws RemoteException {
1628        if (code == SYSPROPS_TRANSACTION) {
1629            // We need to tell all apps about the system property change.
1630            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1631            synchronized(this) {
1632                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1633                    final int NA = apps.size();
1634                    for (int ia=0; ia<NA; ia++) {
1635                        ProcessRecord app = apps.valueAt(ia);
1636                        if (app.thread != null) {
1637                            procs.add(app.thread.asBinder());
1638                        }
1639                    }
1640                }
1641            }
1642
1643            int N = procs.size();
1644            for (int i=0; i<N; i++) {
1645                Parcel data2 = Parcel.obtain();
1646                try {
1647                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1648                } catch (RemoteException e) {
1649                }
1650                data2.recycle();
1651            }
1652        }
1653        try {
1654            return super.onTransact(code, data, reply, flags);
1655        } catch (RuntimeException e) {
1656            // The activity manager only throws security exceptions, so let's
1657            // log all others.
1658            if (!(e instanceof SecurityException)) {
1659                Slog.e(TAG, "Activity Manager Crash", e);
1660            }
1661            throw e;
1662        }
1663    }
1664
1665    void updateCpuStats() {
1666        final long now = SystemClock.uptimeMillis();
1667        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1668            return;
1669        }
1670        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1671            synchronized (mProcessStatsThread) {
1672                mProcessStatsThread.notify();
1673            }
1674        }
1675    }
1676
1677    void updateCpuStatsNow() {
1678        synchronized (mProcessStatsThread) {
1679            mProcessStatsMutexFree.set(false);
1680            final long now = SystemClock.uptimeMillis();
1681            boolean haveNewCpuStats = false;
1682
1683            if (MONITOR_CPU_USAGE &&
1684                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1685                mLastCpuTime.set(now);
1686                haveNewCpuStats = true;
1687                mProcessStats.update();
1688                //Slog.i(TAG, mProcessStats.printCurrentState());
1689                //Slog.i(TAG, "Total CPU usage: "
1690                //        + mProcessStats.getTotalCpuPercent() + "%");
1691
1692                // Slog the cpu usage if the property is set.
1693                if ("true".equals(SystemProperties.get("events.cpu"))) {
1694                    int user = mProcessStats.getLastUserTime();
1695                    int system = mProcessStats.getLastSystemTime();
1696                    int iowait = mProcessStats.getLastIoWaitTime();
1697                    int irq = mProcessStats.getLastIrqTime();
1698                    int softIrq = mProcessStats.getLastSoftIrqTime();
1699                    int idle = mProcessStats.getLastIdleTime();
1700
1701                    int total = user + system + iowait + irq + softIrq + idle;
1702                    if (total == 0) total = 1;
1703
1704                    EventLog.writeEvent(EventLogTags.CPU,
1705                            ((user+system+iowait+irq+softIrq) * 100) / total,
1706                            (user * 100) / total,
1707                            (system * 100) / total,
1708                            (iowait * 100) / total,
1709                            (irq * 100) / total,
1710                            (softIrq * 100) / total);
1711                }
1712            }
1713
1714            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1715            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1716            synchronized(bstats) {
1717                synchronized(mPidsSelfLocked) {
1718                    if (haveNewCpuStats) {
1719                        if (mOnBattery) {
1720                            int perc = bstats.startAddingCpuLocked();
1721                            int totalUTime = 0;
1722                            int totalSTime = 0;
1723                            final int N = mProcessStats.countStats();
1724                            for (int i=0; i<N; i++) {
1725                                ProcessStats.Stats st = mProcessStats.getStats(i);
1726                                if (!st.working) {
1727                                    continue;
1728                                }
1729                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1730                                int otherUTime = (st.rel_utime*perc)/100;
1731                                int otherSTime = (st.rel_stime*perc)/100;
1732                                totalUTime += otherUTime;
1733                                totalSTime += otherSTime;
1734                                if (pr != null) {
1735                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1736                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1737                                            st.rel_stime-otherSTime);
1738                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1739                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1740                                } else {
1741                                    BatteryStatsImpl.Uid.Proc ps =
1742                                            bstats.getProcessStatsLocked(st.name, st.pid);
1743                                    if (ps != null) {
1744                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1745                                                st.rel_stime-otherSTime);
1746                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1747                                    }
1748                                }
1749                            }
1750                            bstats.finishAddingCpuLocked(perc, totalUTime,
1751                                    totalSTime, cpuSpeedTimes);
1752                        }
1753                    }
1754                }
1755
1756                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1757                    mLastWriteTime = now;
1758                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1759                }
1760            }
1761        }
1762    }
1763
1764    @Override
1765    public void batteryNeedsCpuUpdate() {
1766        updateCpuStatsNow();
1767    }
1768
1769    @Override
1770    public void batteryPowerChanged(boolean onBattery) {
1771        // When plugging in, update the CPU stats first before changing
1772        // the plug state.
1773        updateCpuStatsNow();
1774        synchronized (this) {
1775            synchronized(mPidsSelfLocked) {
1776                mOnBattery = DEBUG_POWER ? true : onBattery;
1777            }
1778        }
1779    }
1780
1781    /**
1782     * Initialize the application bind args. These are passed to each
1783     * process when the bindApplication() IPC is sent to the process. They're
1784     * lazily setup to make sure the services are running when they're asked for.
1785     */
1786    private HashMap<String, IBinder> getCommonServicesLocked() {
1787        if (mAppBindArgs == null) {
1788            mAppBindArgs = new HashMap<String, IBinder>();
1789
1790            // Setup the application init args
1791            mAppBindArgs.put("package", ServiceManager.getService("package"));
1792            mAppBindArgs.put("window", ServiceManager.getService("window"));
1793            mAppBindArgs.put(Context.ALARM_SERVICE,
1794                    ServiceManager.getService(Context.ALARM_SERVICE));
1795        }
1796        return mAppBindArgs;
1797    }
1798
1799    final void setFocusedActivityLocked(ActivityRecord r) {
1800        if (mFocusedActivity != r) {
1801            mFocusedActivity = r;
1802            if (r != null) {
1803                mWindowManager.setFocusedApp(r.appToken, true);
1804            }
1805        }
1806    }
1807
1808    private final void updateLruProcessInternalLocked(ProcessRecord app,
1809            boolean updateActivityTime, int bestPos) {
1810        // put it on the LRU to keep track of when it should be exited.
1811        int lrui = mLruProcesses.indexOf(app);
1812        if (lrui >= 0) mLruProcesses.remove(lrui);
1813
1814        int i = mLruProcesses.size()-1;
1815        int skipTop = 0;
1816
1817        app.lruSeq = mLruSeq;
1818
1819        // compute the new weight for this process.
1820        if (updateActivityTime) {
1821            app.lastActivityTime = SystemClock.uptimeMillis();
1822        }
1823        if (app.activities.size() > 0) {
1824            // If this process has activities, we more strongly want to keep
1825            // it around.
1826            app.lruWeight = app.lastActivityTime;
1827        } else if (app.pubProviders.size() > 0) {
1828            // If this process contains content providers, we want to keep
1829            // it a little more strongly.
1830            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1831            // Also don't let it kick out the first few "real" hidden processes.
1832            skipTop = ProcessList.MIN_HIDDEN_APPS;
1833        } else {
1834            // If this process doesn't have activities, we less strongly
1835            // want to keep it around, and generally want to avoid getting
1836            // in front of any very recently used activities.
1837            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1838            // Also don't let it kick out the first few "real" hidden processes.
1839            skipTop = ProcessList.MIN_HIDDEN_APPS;
1840        }
1841
1842        while (i >= 0) {
1843            ProcessRecord p = mLruProcesses.get(i);
1844            // If this app shouldn't be in front of the first N background
1845            // apps, then skip over that many that are currently hidden.
1846            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1847                skipTop--;
1848            }
1849            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1850                mLruProcesses.add(i+1, app);
1851                break;
1852            }
1853            i--;
1854        }
1855        if (i < 0) {
1856            mLruProcesses.add(0, app);
1857        }
1858
1859        // If the app is currently using a content provider or service,
1860        // bump those processes as well.
1861        if (app.connections.size() > 0) {
1862            for (ConnectionRecord cr : app.connections) {
1863                if (cr.binding != null && cr.binding.service != null
1864                        && cr.binding.service.app != null
1865                        && cr.binding.service.app.lruSeq != mLruSeq) {
1866                    updateLruProcessInternalLocked(cr.binding.service.app,
1867                            updateActivityTime, i+1);
1868                }
1869            }
1870        }
1871        for (int j=app.conProviders.size()-1; j>=0; j--) {
1872            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1873            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1874                updateLruProcessInternalLocked(cpr.proc,
1875                        updateActivityTime, i+1);
1876            }
1877        }
1878    }
1879
1880    final void updateLruProcessLocked(ProcessRecord app,
1881            boolean oomAdj, boolean updateActivityTime) {
1882        mLruSeq++;
1883        updateLruProcessInternalLocked(app, updateActivityTime, 0);
1884
1885        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1886        if (oomAdj) {
1887            updateOomAdjLocked();
1888        }
1889    }
1890
1891    final ProcessRecord getProcessRecordLocked(
1892            String processName, int uid) {
1893        if (uid == Process.SYSTEM_UID) {
1894            // The system gets to run in any process.  If there are multiple
1895            // processes with the same uid, just pick the first (this
1896            // should never happen).
1897            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1898                    processName);
1899            if (procs == null) return null;
1900            final int N = procs.size();
1901            for (int i = 0; i < N; i++) {
1902                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1903            }
1904        }
1905        ProcessRecord proc = mProcessNames.get(processName, uid);
1906        return proc;
1907    }
1908
1909    void ensurePackageDexOpt(String packageName) {
1910        IPackageManager pm = AppGlobals.getPackageManager();
1911        try {
1912            if (pm.performDexOpt(packageName)) {
1913                mDidDexOpt = true;
1914            }
1915        } catch (RemoteException e) {
1916        }
1917    }
1918
1919    boolean isNextTransitionForward() {
1920        int transit = mWindowManager.getPendingAppTransition();
1921        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1922                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1923                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1924    }
1925
1926    final ProcessRecord startProcessLocked(String processName,
1927            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1928            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1929            boolean isolated) {
1930        ProcessRecord app;
1931        if (!isolated) {
1932            app = getProcessRecordLocked(processName, info.uid);
1933        } else {
1934            // If this is an isolated process, it can't re-use an existing process.
1935            app = null;
1936        }
1937        // We don't have to do anything more if:
1938        // (1) There is an existing application record; and
1939        // (2) The caller doesn't think it is dead, OR there is no thread
1940        //     object attached to it so we know it couldn't have crashed; and
1941        // (3) There is a pid assigned to it, so it is either starting or
1942        //     already running.
1943        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1944                + " app=" + app + " knownToBeDead=" + knownToBeDead
1945                + " thread=" + (app != null ? app.thread : null)
1946                + " pid=" + (app != null ? app.pid : -1));
1947        if (app != null && app.pid > 0) {
1948            if (!knownToBeDead || app.thread == null) {
1949                // We already have the app running, or are waiting for it to
1950                // come up (we have a pid but not yet its thread), so keep it.
1951                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1952                // If this is a new package in the process, add the package to the list
1953                app.addPackage(info.packageName);
1954                return app;
1955            } else {
1956                // An application record is attached to a previous process,
1957                // clean it up now.
1958                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1959                handleAppDiedLocked(app, true, true);
1960            }
1961        }
1962
1963        String hostingNameStr = hostingName != null
1964                ? hostingName.flattenToShortString() : null;
1965
1966        if (!isolated) {
1967            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1968                // If we are in the background, then check to see if this process
1969                // is bad.  If so, we will just silently fail.
1970                if (mBadProcesses.get(info.processName, info.uid) != null) {
1971                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1972                            + "/" + info.processName);
1973                    return null;
1974                }
1975            } else {
1976                // When the user is explicitly starting a process, then clear its
1977                // crash count so that we won't make it bad until they see at
1978                // least one crash dialog again, and make the process good again
1979                // if it had been bad.
1980                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1981                        + "/" + info.processName);
1982                mProcessCrashTimes.remove(info.processName, info.uid);
1983                if (mBadProcesses.get(info.processName, info.uid) != null) {
1984                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1985                            info.processName);
1986                    mBadProcesses.remove(info.processName, info.uid);
1987                    if (app != null) {
1988                        app.bad = false;
1989                    }
1990                }
1991            }
1992        }
1993
1994        if (app == null) {
1995            app = newProcessRecordLocked(null, info, processName, isolated);
1996            if (app == null) {
1997                Slog.w(TAG, "Failed making new process record for "
1998                        + processName + "/" + info.uid + " isolated=" + isolated);
1999                return null;
2000            }
2001            mProcessNames.put(processName, app.uid, app);
2002            if (isolated) {
2003                mIsolatedProcesses.put(app.uid, app);
2004            }
2005        } else {
2006            // If this is a new package in the process, add the package to the list
2007            app.addPackage(info.packageName);
2008        }
2009
2010        // If the system is not ready yet, then hold off on starting this
2011        // process until it is.
2012        if (!mProcessesReady
2013                && !isAllowedWhileBooting(info)
2014                && !allowWhileBooting) {
2015            if (!mProcessesOnHold.contains(app)) {
2016                mProcessesOnHold.add(app);
2017            }
2018            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2019            return app;
2020        }
2021
2022        startProcessLocked(app, hostingType, hostingNameStr);
2023        return (app.pid != 0) ? app : null;
2024    }
2025
2026    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2027        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2028    }
2029
2030    private final void startProcessLocked(ProcessRecord app,
2031            String hostingType, String hostingNameStr) {
2032        if (app.pid > 0 && app.pid != MY_PID) {
2033            synchronized (mPidsSelfLocked) {
2034                mPidsSelfLocked.remove(app.pid);
2035                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2036            }
2037            app.setPid(0);
2038        }
2039
2040        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2041                "startProcessLocked removing on hold: " + app);
2042        mProcessesOnHold.remove(app);
2043
2044        updateCpuStats();
2045
2046        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2047        mProcDeaths[0] = 0;
2048
2049        try {
2050            int uid = app.uid;
2051
2052            int[] gids = null;
2053            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2054            if (!app.isolated) {
2055                int[] permGids = null;
2056                try {
2057                    final PackageManager pm = mContext.getPackageManager();
2058                    permGids = pm.getPackageGids(app.info.packageName);
2059
2060                    if (Environment.isExternalStorageEmulated()) {
2061                        if (pm.checkPermission(
2062                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2063                                app.info.packageName) == PERMISSION_GRANTED) {
2064                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2065                        } else {
2066                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2067                        }
2068                    }
2069                } catch (PackageManager.NameNotFoundException e) {
2070                    Slog.w(TAG, "Unable to retrieve gids", e);
2071                }
2072
2073                /*
2074                 * Add shared application GID so applications can share some
2075                 * resources like shared libraries
2076                 */
2077                if (permGids == null) {
2078                    gids = new int[1];
2079                } else {
2080                    gids = new int[permGids.length + 1];
2081                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2082                }
2083                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2084            }
2085            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2086                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2087                        && mTopComponent != null
2088                        && app.processName.equals(mTopComponent.getPackageName())) {
2089                    uid = 0;
2090                }
2091                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2092                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2093                    uid = 0;
2094                }
2095            }
2096            int debugFlags = 0;
2097            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2098                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2099                // Also turn on CheckJNI for debuggable apps. It's quite
2100                // awkward to turn on otherwise.
2101                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2102            }
2103            // Run the app in safe mode if its manifest requests so or the
2104            // system is booted in safe mode.
2105            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2106                Zygote.systemInSafeMode == true) {
2107                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2108            }
2109            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2110                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2111            }
2112            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2113                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2114            }
2115            if ("1".equals(SystemProperties.get("debug.assert"))) {
2116                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2117            }
2118
2119            // Start the process.  It will either succeed and return a result containing
2120            // the PID of the new process, or else throw a RuntimeException.
2121            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2122                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2123                    app.info.targetSdkVersion, null, null);
2124
2125            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2126            synchronized (bs) {
2127                if (bs.isOnBattery()) {
2128                    app.batteryStats.incStartsLocked();
2129                }
2130            }
2131
2132            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2133                    app.processName, hostingType,
2134                    hostingNameStr != null ? hostingNameStr : "");
2135
2136            if (app.persistent) {
2137                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2138            }
2139
2140            StringBuilder buf = mStringBuilder;
2141            buf.setLength(0);
2142            buf.append("Start proc ");
2143            buf.append(app.processName);
2144            buf.append(" for ");
2145            buf.append(hostingType);
2146            if (hostingNameStr != null) {
2147                buf.append(" ");
2148                buf.append(hostingNameStr);
2149            }
2150            buf.append(": pid=");
2151            buf.append(startResult.pid);
2152            buf.append(" uid=");
2153            buf.append(uid);
2154            buf.append(" gids={");
2155            if (gids != null) {
2156                for (int gi=0; gi<gids.length; gi++) {
2157                    if (gi != 0) buf.append(", ");
2158                    buf.append(gids[gi]);
2159
2160                }
2161            }
2162            buf.append("}");
2163            Slog.i(TAG, buf.toString());
2164            app.setPid(startResult.pid);
2165            app.usingWrapper = startResult.usingWrapper;
2166            app.removed = false;
2167            synchronized (mPidsSelfLocked) {
2168                this.mPidsSelfLocked.put(startResult.pid, app);
2169                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2170                msg.obj = app;
2171                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2172                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2173            }
2174        } catch (RuntimeException e) {
2175            // XXX do better error recovery.
2176            app.setPid(0);
2177            Slog.e(TAG, "Failure starting process " + app.processName, e);
2178        }
2179    }
2180
2181    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2182        if (resumed) {
2183            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2184        } else {
2185            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2186        }
2187    }
2188
2189    boolean startHomeActivityLocked(int userId) {
2190        if (mHeadless) {
2191            // Added because none of the other calls to ensureBootCompleted seem to fire
2192            // when running headless.
2193            ensureBootCompleted();
2194            return false;
2195        }
2196
2197        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2198                && mTopAction == null) {
2199            // We are running in factory test mode, but unable to find
2200            // the factory test app, so just sit around displaying the
2201            // error message and don't try to start anything.
2202            return false;
2203        }
2204        Intent intent = new Intent(
2205            mTopAction,
2206            mTopData != null ? Uri.parse(mTopData) : null);
2207        intent.setComponent(mTopComponent);
2208        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2209            intent.addCategory(Intent.CATEGORY_HOME);
2210        }
2211        ActivityInfo aInfo =
2212            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2213        if (aInfo != null) {
2214            intent.setComponent(new ComponentName(
2215                    aInfo.applicationInfo.packageName, aInfo.name));
2216            // Don't do this if the home app is currently being
2217            // instrumented.
2218            aInfo = new ActivityInfo(aInfo);
2219            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2220            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2221                    aInfo.applicationInfo.uid);
2222            if (app == null || app.instrumentationClass == null) {
2223                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2224                mMainStack.startActivityLocked(null, intent, null, aInfo,
2225                        null, null, 0, 0, 0, 0, null, false, null);
2226            }
2227        }
2228
2229        return true;
2230    }
2231
2232    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2233        ActivityInfo ai = null;
2234        ComponentName comp = intent.getComponent();
2235        try {
2236            if (comp != null) {
2237                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2238            } else {
2239                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2240                        intent,
2241                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2242                            flags, userId);
2243
2244                if (info != null) {
2245                    ai = info.activityInfo;
2246                }
2247            }
2248        } catch (RemoteException e) {
2249            // ignore
2250        }
2251
2252        return ai;
2253    }
2254
2255    /**
2256     * Starts the "new version setup screen" if appropriate.
2257     */
2258    void startSetupActivityLocked() {
2259        // Only do this once per boot.
2260        if (mCheckedForSetup) {
2261            return;
2262        }
2263
2264        // We will show this screen if the current one is a different
2265        // version than the last one shown, and we are not running in
2266        // low-level factory test mode.
2267        final ContentResolver resolver = mContext.getContentResolver();
2268        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2269                Settings.Global.getInt(resolver,
2270                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2271            mCheckedForSetup = true;
2272
2273            // See if we should be showing the platform update setup UI.
2274            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2275            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2276                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2277
2278            // We don't allow third party apps to replace this.
2279            ResolveInfo ri = null;
2280            for (int i=0; ris != null && i<ris.size(); i++) {
2281                if ((ris.get(i).activityInfo.applicationInfo.flags
2282                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2283                    ri = ris.get(i);
2284                    break;
2285                }
2286            }
2287
2288            if (ri != null) {
2289                String vers = ri.activityInfo.metaData != null
2290                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2291                        : null;
2292                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2293                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2294                            Intent.METADATA_SETUP_VERSION);
2295                }
2296                String lastVers = Settings.Secure.getString(
2297                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2298                if (vers != null && !vers.equals(lastVers)) {
2299                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2300                    intent.setComponent(new ComponentName(
2301                            ri.activityInfo.packageName, ri.activityInfo.name));
2302                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2303                            null, null, 0, 0, 0, 0, null, false, null);
2304                }
2305            }
2306        }
2307    }
2308
2309    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2310        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2311    }
2312
2313    void enforceNotIsolatedCaller(String caller) {
2314        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2315            throw new SecurityException("Isolated process not allowed to call " + caller);
2316        }
2317    }
2318
2319    public int getFrontActivityScreenCompatMode() {
2320        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2321        synchronized (this) {
2322            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2323        }
2324    }
2325
2326    public void setFrontActivityScreenCompatMode(int mode) {
2327        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2328                "setFrontActivityScreenCompatMode");
2329        synchronized (this) {
2330            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2331        }
2332    }
2333
2334    public int getPackageScreenCompatMode(String packageName) {
2335        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2336        synchronized (this) {
2337            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2338        }
2339    }
2340
2341    public void setPackageScreenCompatMode(String packageName, int mode) {
2342        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2343                "setPackageScreenCompatMode");
2344        synchronized (this) {
2345            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2346        }
2347    }
2348
2349    public boolean getPackageAskScreenCompat(String packageName) {
2350        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2351        synchronized (this) {
2352            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2353        }
2354    }
2355
2356    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2357        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2358                "setPackageAskScreenCompat");
2359        synchronized (this) {
2360            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2361        }
2362    }
2363
2364    void reportResumedActivityLocked(ActivityRecord r) {
2365        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2366        updateUsageStats(r, true);
2367    }
2368
2369    private void dispatchProcessesChanged() {
2370        int N;
2371        synchronized (this) {
2372            N = mPendingProcessChanges.size();
2373            if (mActiveProcessChanges.length < N) {
2374                mActiveProcessChanges = new ProcessChangeItem[N];
2375            }
2376            mPendingProcessChanges.toArray(mActiveProcessChanges);
2377            mAvailProcessChanges.addAll(mPendingProcessChanges);
2378            mPendingProcessChanges.clear();
2379            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2380        }
2381        int i = mProcessObservers.beginBroadcast();
2382        while (i > 0) {
2383            i--;
2384            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2385            if (observer != null) {
2386                try {
2387                    for (int j=0; j<N; j++) {
2388                        ProcessChangeItem item = mActiveProcessChanges[j];
2389                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2390                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2391                                    + item.pid + " uid=" + item.uid + ": "
2392                                    + item.foregroundActivities);
2393                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2394                                    item.foregroundActivities);
2395                        }
2396                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2397                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2398                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2399                            observer.onImportanceChanged(item.pid, item.uid,
2400                                    item.importance);
2401                        }
2402                    }
2403                } catch (RemoteException e) {
2404                }
2405            }
2406        }
2407        mProcessObservers.finishBroadcast();
2408    }
2409
2410    private void dispatchProcessDied(int pid, int uid) {
2411        int i = mProcessObservers.beginBroadcast();
2412        while (i > 0) {
2413            i--;
2414            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2415            if (observer != null) {
2416                try {
2417                    observer.onProcessDied(pid, uid);
2418                } catch (RemoteException e) {
2419                }
2420            }
2421        }
2422        mProcessObservers.finishBroadcast();
2423    }
2424
2425    final void doPendingActivityLaunchesLocked(boolean doResume) {
2426        final int N = mPendingActivityLaunches.size();
2427        if (N <= 0) {
2428            return;
2429        }
2430        for (int i=0; i<N; i++) {
2431            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2432            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2433                    pal.startFlags, doResume && i == (N-1), null);
2434        }
2435        mPendingActivityLaunches.clear();
2436    }
2437
2438    public final int startActivity(IApplicationThread caller,
2439            Intent intent, String resolvedType, IBinder resultTo,
2440            String resultWho, int requestCode, int startFlags,
2441            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2442        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2443                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2444    }
2445
2446    public final int startActivityAsUser(IApplicationThread caller,
2447            Intent intent, String resolvedType, IBinder resultTo,
2448            String resultWho, int requestCode, int startFlags,
2449            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2450        enforceNotIsolatedCaller("startActivity");
2451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2452                false, true, "startActivity", null);
2453        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2454                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2455                null, null, options, userId);
2456    }
2457
2458    public final WaitResult startActivityAndWait(IApplicationThread caller,
2459            Intent intent, String resolvedType, IBinder resultTo,
2460            String resultWho, int requestCode, int startFlags, String profileFile,
2461            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2462        enforceNotIsolatedCaller("startActivityAndWait");
2463        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2464                false, true, "startActivityAndWait", null);
2465        WaitResult res = new WaitResult();
2466        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2467                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2468                res, null, options, UserHandle.getCallingUserId());
2469        return res;
2470    }
2471
2472    public final int startActivityWithConfig(IApplicationThread caller,
2473            Intent intent, String resolvedType, IBinder resultTo,
2474            String resultWho, int requestCode, int startFlags, Configuration config,
2475            Bundle options, int userId) {
2476        enforceNotIsolatedCaller("startActivityWithConfig");
2477        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2478                false, true, "startActivityWithConfig", null);
2479        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2480                resultTo, resultWho, requestCode, startFlags,
2481                null, null, null, config, options, userId);
2482        return ret;
2483    }
2484
2485    public int startActivityIntentSender(IApplicationThread caller,
2486            IntentSender intent, Intent fillInIntent, String resolvedType,
2487            IBinder resultTo, String resultWho, int requestCode,
2488            int flagsMask, int flagsValues, Bundle options) {
2489        enforceNotIsolatedCaller("startActivityIntentSender");
2490        // Refuse possible leaked file descriptors
2491        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2492            throw new IllegalArgumentException("File descriptors passed in Intent");
2493        }
2494
2495        IIntentSender sender = intent.getTarget();
2496        if (!(sender instanceof PendingIntentRecord)) {
2497            throw new IllegalArgumentException("Bad PendingIntent object");
2498        }
2499
2500        PendingIntentRecord pir = (PendingIntentRecord)sender;
2501
2502        synchronized (this) {
2503            // If this is coming from the currently resumed activity, it is
2504            // effectively saying that app switches are allowed at this point.
2505            if (mMainStack.mResumedActivity != null
2506                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2507                            Binder.getCallingUid()) {
2508                mAppSwitchesAllowedTime = 0;
2509            }
2510        }
2511        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2512                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2513        return ret;
2514    }
2515
2516    public boolean startNextMatchingActivity(IBinder callingActivity,
2517            Intent intent, Bundle options) {
2518        // Refuse possible leaked file descriptors
2519        if (intent != null && intent.hasFileDescriptors() == true) {
2520            throw new IllegalArgumentException("File descriptors passed in Intent");
2521        }
2522
2523        synchronized (this) {
2524            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2525            if (r == null) {
2526                ActivityOptions.abort(options);
2527                return false;
2528            }
2529            if (r.app == null || r.app.thread == null) {
2530                // The caller is not running...  d'oh!
2531                ActivityOptions.abort(options);
2532                return false;
2533            }
2534            intent = new Intent(intent);
2535            // The caller is not allowed to change the data.
2536            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2537            // And we are resetting to find the next component...
2538            intent.setComponent(null);
2539
2540            ActivityInfo aInfo = null;
2541            try {
2542                List<ResolveInfo> resolves =
2543                    AppGlobals.getPackageManager().queryIntentActivities(
2544                            intent, r.resolvedType,
2545                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2546                            UserHandle.getCallingUserId());
2547
2548                // Look for the original activity in the list...
2549                final int N = resolves != null ? resolves.size() : 0;
2550                for (int i=0; i<N; i++) {
2551                    ResolveInfo rInfo = resolves.get(i);
2552                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2553                            && rInfo.activityInfo.name.equals(r.info.name)) {
2554                        // We found the current one...  the next matching is
2555                        // after it.
2556                        i++;
2557                        if (i<N) {
2558                            aInfo = resolves.get(i).activityInfo;
2559                        }
2560                        break;
2561                    }
2562                }
2563            } catch (RemoteException e) {
2564            }
2565
2566            if (aInfo == null) {
2567                // Nobody who is next!
2568                ActivityOptions.abort(options);
2569                return false;
2570            }
2571
2572            intent.setComponent(new ComponentName(
2573                    aInfo.applicationInfo.packageName, aInfo.name));
2574            intent.setFlags(intent.getFlags()&~(
2575                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2576                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2577                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2578                    Intent.FLAG_ACTIVITY_NEW_TASK));
2579
2580            // Okay now we need to start the new activity, replacing the
2581            // currently running activity.  This is a little tricky because
2582            // we want to start the new one as if the current one is finished,
2583            // but not finish the current one first so that there is no flicker.
2584            // And thus...
2585            final boolean wasFinishing = r.finishing;
2586            r.finishing = true;
2587
2588            // Propagate reply information over to the new activity.
2589            final ActivityRecord resultTo = r.resultTo;
2590            final String resultWho = r.resultWho;
2591            final int requestCode = r.requestCode;
2592            r.resultTo = null;
2593            if (resultTo != null) {
2594                resultTo.removeResultsLocked(r, resultWho, requestCode);
2595            }
2596
2597            final long origId = Binder.clearCallingIdentity();
2598            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2599                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2600                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2601                    options, false, null);
2602            Binder.restoreCallingIdentity(origId);
2603
2604            r.finishing = wasFinishing;
2605            if (res != ActivityManager.START_SUCCESS) {
2606                return false;
2607            }
2608            return true;
2609        }
2610    }
2611
2612    final int startActivityInPackage(int uid,
2613            Intent intent, String resolvedType, IBinder resultTo,
2614            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2615
2616        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2617                false, true, "startActivityInPackage", null);
2618
2619        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2620                resultTo, resultWho, requestCode, startFlags,
2621                null, null, null, null, options, userId);
2622        return ret;
2623    }
2624
2625    public final int startActivities(IApplicationThread caller,
2626            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2627            int userId) {
2628        enforceNotIsolatedCaller("startActivities");
2629        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2630                false, true, "startActivity", null);
2631        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2632                options, userId);
2633        return ret;
2634    }
2635
2636    final int startActivitiesInPackage(int uid,
2637            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2638            Bundle options, int userId) {
2639
2640        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2641                false, true, "startActivityInPackage", null);
2642        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2643                options, userId);
2644        return ret;
2645    }
2646
2647    final void addRecentTaskLocked(TaskRecord task) {
2648        int N = mRecentTasks.size();
2649        // Quick case: check if the top-most recent task is the same.
2650        if (N > 0 && mRecentTasks.get(0) == task) {
2651            return;
2652        }
2653        // Remove any existing entries that are the same kind of task.
2654        for (int i=0; i<N; i++) {
2655            TaskRecord tr = mRecentTasks.get(i);
2656            if (task.userId == tr.userId
2657                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2658                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2659                mRecentTasks.remove(i);
2660                i--;
2661                N--;
2662                if (task.intent == null) {
2663                    // If the new recent task we are adding is not fully
2664                    // specified, then replace it with the existing recent task.
2665                    task = tr;
2666                }
2667            }
2668        }
2669        if (N >= MAX_RECENT_TASKS) {
2670            mRecentTasks.remove(N-1);
2671        }
2672        mRecentTasks.add(0, task);
2673    }
2674
2675    public void setRequestedOrientation(IBinder token,
2676            int requestedOrientation) {
2677        synchronized (this) {
2678            ActivityRecord r = mMainStack.isInStackLocked(token);
2679            if (r == null) {
2680                return;
2681            }
2682            final long origId = Binder.clearCallingIdentity();
2683            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2684            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2685                    mConfiguration,
2686                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2687            if (config != null) {
2688                r.frozenBeforeDestroy = true;
2689                if (!updateConfigurationLocked(config, r, false, false)) {
2690                    mMainStack.resumeTopActivityLocked(null);
2691                }
2692            }
2693            Binder.restoreCallingIdentity(origId);
2694        }
2695    }
2696
2697    public int getRequestedOrientation(IBinder token) {
2698        synchronized (this) {
2699            ActivityRecord r = mMainStack.isInStackLocked(token);
2700            if (r == null) {
2701                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2702            }
2703            return mWindowManager.getAppOrientation(r.appToken);
2704        }
2705    }
2706
2707    /**
2708     * This is the internal entry point for handling Activity.finish().
2709     *
2710     * @param token The Binder token referencing the Activity we want to finish.
2711     * @param resultCode Result code, if any, from this Activity.
2712     * @param resultData Result data (Intent), if any, from this Activity.
2713     *
2714     * @return Returns true if the activity successfully finished, or false if it is still running.
2715     */
2716    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2717        // Refuse possible leaked file descriptors
2718        if (resultData != null && resultData.hasFileDescriptors() == true) {
2719            throw new IllegalArgumentException("File descriptors passed in Intent");
2720        }
2721
2722        synchronized(this) {
2723            if (mController != null) {
2724                // Find the first activity that is not finishing.
2725                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2726                if (next != null) {
2727                    // ask watcher if this is allowed
2728                    boolean resumeOK = true;
2729                    try {
2730                        resumeOK = mController.activityResuming(next.packageName);
2731                    } catch (RemoteException e) {
2732                        mController = null;
2733                    }
2734
2735                    if (!resumeOK) {
2736                        return false;
2737                    }
2738                }
2739            }
2740            final long origId = Binder.clearCallingIdentity();
2741            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2742                    resultData, "app-request", true);
2743            Binder.restoreCallingIdentity(origId);
2744            return res;
2745        }
2746    }
2747
2748    public final void finishHeavyWeightApp() {
2749        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2750                != PackageManager.PERMISSION_GRANTED) {
2751            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2752                    + Binder.getCallingPid()
2753                    + ", uid=" + Binder.getCallingUid()
2754                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2755            Slog.w(TAG, msg);
2756            throw new SecurityException(msg);
2757        }
2758
2759        synchronized(this) {
2760            if (mHeavyWeightProcess == null) {
2761                return;
2762            }
2763
2764            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2765                    mHeavyWeightProcess.activities);
2766            for (int i=0; i<activities.size(); i++) {
2767                ActivityRecord r = activities.get(i);
2768                if (!r.finishing) {
2769                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2770                    if (index >= 0) {
2771                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2772                                null, "finish-heavy", true);
2773                    }
2774                }
2775            }
2776
2777            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2778                    mHeavyWeightProcess.userId, 0));
2779            mHeavyWeightProcess = null;
2780        }
2781    }
2782
2783    public void crashApplication(int uid, int initialPid, String packageName,
2784            String message) {
2785        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2786                != PackageManager.PERMISSION_GRANTED) {
2787            String msg = "Permission Denial: crashApplication() from pid="
2788                    + Binder.getCallingPid()
2789                    + ", uid=" + Binder.getCallingUid()
2790                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2791            Slog.w(TAG, msg);
2792            throw new SecurityException(msg);
2793        }
2794
2795        synchronized(this) {
2796            ProcessRecord proc = null;
2797
2798            // Figure out which process to kill.  We don't trust that initialPid
2799            // still has any relation to current pids, so must scan through the
2800            // list.
2801            synchronized (mPidsSelfLocked) {
2802                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2803                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2804                    if (p.uid != uid) {
2805                        continue;
2806                    }
2807                    if (p.pid == initialPid) {
2808                        proc = p;
2809                        break;
2810                    }
2811                    for (String str : p.pkgList) {
2812                        if (str.equals(packageName)) {
2813                            proc = p;
2814                        }
2815                    }
2816                }
2817            }
2818
2819            if (proc == null) {
2820                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2821                        + " initialPid=" + initialPid
2822                        + " packageName=" + packageName);
2823                return;
2824            }
2825
2826            if (proc.thread != null) {
2827                if (proc.pid == Process.myPid()) {
2828                    Log.w(TAG, "crashApplication: trying to crash self!");
2829                    return;
2830                }
2831                long ident = Binder.clearCallingIdentity();
2832                try {
2833                    proc.thread.scheduleCrash(message);
2834                } catch (RemoteException e) {
2835                }
2836                Binder.restoreCallingIdentity(ident);
2837            }
2838        }
2839    }
2840
2841    public final void finishSubActivity(IBinder token, String resultWho,
2842            int requestCode) {
2843        synchronized(this) {
2844            final long origId = Binder.clearCallingIdentity();
2845            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2846            Binder.restoreCallingIdentity(origId);
2847        }
2848    }
2849
2850    public boolean finishActivityAffinity(IBinder token) {
2851        synchronized(this) {
2852            final long origId = Binder.clearCallingIdentity();
2853            boolean res = mMainStack.finishActivityAffinityLocked(token);
2854            Binder.restoreCallingIdentity(origId);
2855            return res;
2856        }
2857    }
2858
2859    public boolean willActivityBeVisible(IBinder token) {
2860        synchronized(this) {
2861            int i;
2862            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2863                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2864                if (r.appToken == token) {
2865                    return true;
2866                }
2867                if (r.fullscreen && !r.finishing) {
2868                    return false;
2869                }
2870            }
2871            return true;
2872        }
2873    }
2874
2875    public void overridePendingTransition(IBinder token, String packageName,
2876            int enterAnim, int exitAnim) {
2877        synchronized(this) {
2878            ActivityRecord self = mMainStack.isInStackLocked(token);
2879            if (self == null) {
2880                return;
2881            }
2882
2883            final long origId = Binder.clearCallingIdentity();
2884
2885            if (self.state == ActivityState.RESUMED
2886                    || self.state == ActivityState.PAUSING) {
2887                mWindowManager.overridePendingAppTransition(packageName,
2888                        enterAnim, exitAnim, null);
2889            }
2890
2891            Binder.restoreCallingIdentity(origId);
2892        }
2893    }
2894
2895    /**
2896     * Main function for removing an existing process from the activity manager
2897     * as a result of that process going away.  Clears out all connections
2898     * to the process.
2899     */
2900    private final void handleAppDiedLocked(ProcessRecord app,
2901            boolean restarting, boolean allowRestart) {
2902        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2903        if (!restarting) {
2904            mLruProcesses.remove(app);
2905        }
2906
2907        if (mProfileProc == app) {
2908            clearProfilerLocked();
2909        }
2910
2911        // Just in case...
2912        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2913            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2914            mMainStack.mPausingActivity = null;
2915        }
2916        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2917            mMainStack.mLastPausedActivity = null;
2918        }
2919
2920        // Remove this application's activities from active lists.
2921        mMainStack.removeHistoryRecordsForAppLocked(app);
2922
2923        boolean atTop = true;
2924        boolean hasVisibleActivities = false;
2925
2926        // Clean out the history list.
2927        int i = mMainStack.mHistory.size();
2928        if (localLOGV) Slog.v(
2929            TAG, "Removing app " + app + " from history with " + i + " entries");
2930        while (i > 0) {
2931            i--;
2932            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2933            if (localLOGV) Slog.v(
2934                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2935            if (r.app == app) {
2936                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2937                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2938                        RuntimeException here = new RuntimeException("here");
2939                        here.fillInStackTrace();
2940                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2941                                + ": haveState=" + r.haveState
2942                                + " stateNotNeeded=" + r.stateNotNeeded
2943                                + " finishing=" + r.finishing
2944                                + " state=" + r.state, here);
2945                    }
2946                    if (!r.finishing) {
2947                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2948                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2949                                System.identityHashCode(r),
2950                                r.task.taskId, r.shortComponentName,
2951                                "proc died without state saved");
2952                    }
2953                    mMainStack.removeActivityFromHistoryLocked(r);
2954
2955                } else {
2956                    // We have the current state for this activity, so
2957                    // it can be restarted later when needed.
2958                    if (localLOGV) Slog.v(
2959                        TAG, "Keeping entry, setting app to null");
2960                    if (r.visible) {
2961                        hasVisibleActivities = true;
2962                    }
2963                    r.app = null;
2964                    r.nowVisible = false;
2965                    if (!r.haveState) {
2966                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2967                                "App died, clearing saved state of " + r);
2968                        r.icicle = null;
2969                    }
2970                }
2971
2972                r.stack.cleanUpActivityLocked(r, true, true);
2973            }
2974            atTop = false;
2975        }
2976
2977        app.activities.clear();
2978
2979        if (app.instrumentationClass != null) {
2980            Slog.w(TAG, "Crash of app " + app.processName
2981                  + " running instrumentation " + app.instrumentationClass);
2982            Bundle info = new Bundle();
2983            info.putString("shortMsg", "Process crashed.");
2984            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2985        }
2986
2987        if (!restarting) {
2988            if (!mMainStack.resumeTopActivityLocked(null)) {
2989                // If there was nothing to resume, and we are not already
2990                // restarting this process, but there is a visible activity that
2991                // is hosted by the process...  then make sure all visible
2992                // activities are running, taking care of restarting this
2993                // process.
2994                if (hasVisibleActivities) {
2995                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2996                }
2997            }
2998        }
2999    }
3000
3001    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3002        IBinder threadBinder = thread.asBinder();
3003        // Find the application record.
3004        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3005            ProcessRecord rec = mLruProcesses.get(i);
3006            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3007                return i;
3008            }
3009        }
3010        return -1;
3011    }
3012
3013    final ProcessRecord getRecordForAppLocked(
3014            IApplicationThread thread) {
3015        if (thread == null) {
3016            return null;
3017        }
3018
3019        int appIndex = getLRURecordIndexForAppLocked(thread);
3020        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3021    }
3022
3023    final void appDiedLocked(ProcessRecord app, int pid,
3024            IApplicationThread thread) {
3025
3026        mProcDeaths[0]++;
3027
3028        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3029        synchronized (stats) {
3030            stats.noteProcessDiedLocked(app.info.uid, pid);
3031        }
3032
3033        // Clean up already done if the process has been re-started.
3034        if (app.pid == pid && app.thread != null &&
3035                app.thread.asBinder() == thread.asBinder()) {
3036            if (!app.killedBackground) {
3037                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3038                        + ") has died.");
3039            }
3040            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3041            if (localLOGV) Slog.v(
3042                TAG, "Dying app: " + app + ", pid: " + pid
3043                + ", thread: " + thread.asBinder());
3044            boolean doLowMem = app.instrumentationClass == null;
3045            handleAppDiedLocked(app, false, true);
3046
3047            if (doLowMem) {
3048                // If there are no longer any background processes running,
3049                // and the app that died was not running instrumentation,
3050                // then tell everyone we are now low on memory.
3051                boolean haveBg = false;
3052                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3053                    ProcessRecord rec = mLruProcesses.get(i);
3054                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3055                        haveBg = true;
3056                        break;
3057                    }
3058                }
3059
3060                if (!haveBg) {
3061                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3062                    long now = SystemClock.uptimeMillis();
3063                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3064                        ProcessRecord rec = mLruProcesses.get(i);
3065                        if (rec != app && rec.thread != null &&
3066                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3067                            // The low memory report is overriding any current
3068                            // state for a GC request.  Make sure to do
3069                            // heavy/important/visible/foreground processes first.
3070                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3071                                rec.lastRequestedGc = 0;
3072                            } else {
3073                                rec.lastRequestedGc = rec.lastLowMemory;
3074                            }
3075                            rec.reportLowMemory = true;
3076                            rec.lastLowMemory = now;
3077                            mProcessesToGc.remove(rec);
3078                            addProcessToGcListLocked(rec);
3079                        }
3080                    }
3081                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3082                    scheduleAppGcsLocked();
3083                }
3084            }
3085        } else if (app.pid != pid) {
3086            // A new process has already been started.
3087            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3088                    + ") has died and restarted (pid " + app.pid + ").");
3089            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3090        } else if (DEBUG_PROCESSES) {
3091            Slog.d(TAG, "Received spurious death notification for thread "
3092                    + thread.asBinder());
3093        }
3094    }
3095
3096    /**
3097     * If a stack trace dump file is configured, dump process stack traces.
3098     * @param clearTraces causes the dump file to be erased prior to the new
3099     *    traces being written, if true; when false, the new traces will be
3100     *    appended to any existing file content.
3101     * @param firstPids of dalvik VM processes to dump stack traces for first
3102     * @param lastPids of dalvik VM processes to dump stack traces for last
3103     * @param nativeProcs optional list of native process names to dump stack crawls
3104     * @return file containing stack traces, or null if no dump file is configured
3105     */
3106    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3107            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3108        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3109        if (tracesPath == null || tracesPath.length() == 0) {
3110            return null;
3111        }
3112
3113        File tracesFile = new File(tracesPath);
3114        try {
3115            File tracesDir = tracesFile.getParentFile();
3116            if (!tracesDir.exists()) {
3117                tracesFile.mkdirs();
3118                if (!SELinux.restorecon(tracesDir)) {
3119                    return null;
3120                }
3121            }
3122            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3123
3124            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3125            tracesFile.createNewFile();
3126            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3127        } catch (IOException e) {
3128            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3129            return null;
3130        }
3131
3132        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3133        return tracesFile;
3134    }
3135
3136    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3137            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3138        // Use a FileObserver to detect when traces finish writing.
3139        // The order of traces is considered important to maintain for legibility.
3140        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3141            public synchronized void onEvent(int event, String path) { notify(); }
3142        };
3143
3144        try {
3145            observer.startWatching();
3146
3147            // First collect all of the stacks of the most important pids.
3148            if (firstPids != null) {
3149                try {
3150                    int num = firstPids.size();
3151                    for (int i = 0; i < num; i++) {
3152                        synchronized (observer) {
3153                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3154                            observer.wait(200);  // Wait for write-close, give up after 200msec
3155                        }
3156                    }
3157                } catch (InterruptedException e) {
3158                    Log.wtf(TAG, e);
3159                }
3160            }
3161
3162            // Next measure CPU usage.
3163            if (processStats != null) {
3164                processStats.init();
3165                System.gc();
3166                processStats.update();
3167                try {
3168                    synchronized (processStats) {
3169                        processStats.wait(500); // measure over 1/2 second.
3170                    }
3171                } catch (InterruptedException e) {
3172                }
3173                processStats.update();
3174
3175                // We'll take the stack crawls of just the top apps using CPU.
3176                final int N = processStats.countWorkingStats();
3177                int numProcs = 0;
3178                for (int i=0; i<N && numProcs<5; i++) {
3179                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3180                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3181                        numProcs++;
3182                        try {
3183                            synchronized (observer) {
3184                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3185                                observer.wait(200);  // Wait for write-close, give up after 200msec
3186                            }
3187                        } catch (InterruptedException e) {
3188                            Log.wtf(TAG, e);
3189                        }
3190
3191                    }
3192                }
3193            }
3194
3195        } finally {
3196            observer.stopWatching();
3197        }
3198
3199        if (nativeProcs != null) {
3200            int[] pids = Process.getPidsForCommands(nativeProcs);
3201            if (pids != null) {
3202                for (int pid : pids) {
3203                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3204                }
3205            }
3206        }
3207    }
3208
3209    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3210        if (true || IS_USER_BUILD) {
3211            return;
3212        }
3213        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3214        if (tracesPath == null || tracesPath.length() == 0) {
3215            return;
3216        }
3217
3218        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3219        StrictMode.allowThreadDiskWrites();
3220        try {
3221            final File tracesFile = new File(tracesPath);
3222            final File tracesDir = tracesFile.getParentFile();
3223            final File tracesTmp = new File(tracesDir, "__tmp__");
3224            try {
3225                if (!tracesDir.exists()) {
3226                    tracesFile.mkdirs();
3227                    if (!SELinux.restorecon(tracesDir.getPath())) {
3228                        return;
3229                    }
3230                }
3231                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3232
3233                if (tracesFile.exists()) {
3234                    tracesTmp.delete();
3235                    tracesFile.renameTo(tracesTmp);
3236                }
3237                StringBuilder sb = new StringBuilder();
3238                Time tobj = new Time();
3239                tobj.set(System.currentTimeMillis());
3240                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3241                sb.append(": ");
3242                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3243                sb.append(" since ");
3244                sb.append(msg);
3245                FileOutputStream fos = new FileOutputStream(tracesFile);
3246                fos.write(sb.toString().getBytes());
3247                if (app == null) {
3248                    fos.write("\n*** No application process!".getBytes());
3249                }
3250                fos.close();
3251                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3252            } catch (IOException e) {
3253                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3254                return;
3255            }
3256
3257            if (app != null) {
3258                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3259                firstPids.add(app.pid);
3260                dumpStackTraces(tracesPath, firstPids, null, null, null);
3261            }
3262
3263            File lastTracesFile = null;
3264            File curTracesFile = null;
3265            for (int i=9; i>=0; i--) {
3266                String name = String.format("slow%02d.txt", i);
3267                curTracesFile = new File(tracesDir, name);
3268                if (curTracesFile.exists()) {
3269                    if (lastTracesFile != null) {
3270                        curTracesFile.renameTo(lastTracesFile);
3271                    } else {
3272                        curTracesFile.delete();
3273                    }
3274                }
3275                lastTracesFile = curTracesFile;
3276            }
3277            tracesFile.renameTo(curTracesFile);
3278            if (tracesTmp.exists()) {
3279                tracesTmp.renameTo(tracesFile);
3280            }
3281        } finally {
3282            StrictMode.setThreadPolicy(oldPolicy);
3283        }
3284    }
3285
3286    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3287            ActivityRecord parent, final String annotation) {
3288        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3289        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3290
3291        if (mController != null) {
3292            try {
3293                // 0 == continue, -1 = kill process immediately
3294                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3295                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3296            } catch (RemoteException e) {
3297                mController = null;
3298            }
3299        }
3300
3301        long anrTime = SystemClock.uptimeMillis();
3302        if (MONITOR_CPU_USAGE) {
3303            updateCpuStatsNow();
3304        }
3305
3306        synchronized (this) {
3307            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3308            if (mShuttingDown) {
3309                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3310                return;
3311            } else if (app.notResponding) {
3312                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3313                return;
3314            } else if (app.crashing) {
3315                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3316                return;
3317            }
3318
3319            // In case we come through here for the same app before completing
3320            // this one, mark as anring now so we will bail out.
3321            app.notResponding = true;
3322
3323            // Log the ANR to the event log.
3324            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3325                    annotation);
3326
3327            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3328            firstPids.add(app.pid);
3329
3330            int parentPid = app.pid;
3331            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3332            if (parentPid != app.pid) firstPids.add(parentPid);
3333
3334            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3335
3336            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3337                ProcessRecord r = mLruProcesses.get(i);
3338                if (r != null && r.thread != null) {
3339                    int pid = r.pid;
3340                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3341                        if (r.persistent) {
3342                            firstPids.add(pid);
3343                        } else {
3344                            lastPids.put(pid, Boolean.TRUE);
3345                        }
3346                    }
3347                }
3348            }
3349        }
3350
3351        // Log the ANR to the main log.
3352        StringBuilder info = new StringBuilder();
3353        info.setLength(0);
3354        info.append("ANR in ").append(app.processName);
3355        if (activity != null && activity.shortComponentName != null) {
3356            info.append(" (").append(activity.shortComponentName).append(")");
3357        }
3358        info.append("\n");
3359        if (annotation != null) {
3360            info.append("Reason: ").append(annotation).append("\n");
3361        }
3362        if (parent != null && parent != activity) {
3363            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3364        }
3365
3366        final ProcessStats processStats = new ProcessStats(true);
3367
3368        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3369
3370        String cpuInfo = null;
3371        if (MONITOR_CPU_USAGE) {
3372            updateCpuStatsNow();
3373            synchronized (mProcessStatsThread) {
3374                cpuInfo = mProcessStats.printCurrentState(anrTime);
3375            }
3376            info.append(processStats.printCurrentLoad());
3377            info.append(cpuInfo);
3378        }
3379
3380        info.append(processStats.printCurrentState(anrTime));
3381
3382        Slog.e(TAG, info.toString());
3383        if (tracesFile == null) {
3384            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3385            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3386        }
3387
3388        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3389                cpuInfo, tracesFile, null);
3390
3391        if (mController != null) {
3392            try {
3393                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3394                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3395                if (res != 0) {
3396                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3397                    return;
3398                }
3399            } catch (RemoteException e) {
3400                mController = null;
3401            }
3402        }
3403
3404        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3405        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3406                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3407
3408        synchronized (this) {
3409            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3410                Slog.w(TAG, "Killing " + app + ": background ANR");
3411                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3412                        app.processName, app.setAdj, "background ANR");
3413                Process.killProcessQuiet(app.pid);
3414                return;
3415            }
3416
3417            // Set the app's notResponding state, and look up the errorReportReceiver
3418            makeAppNotRespondingLocked(app,
3419                    activity != null ? activity.shortComponentName : null,
3420                    annotation != null ? "ANR " + annotation : "ANR",
3421                    info.toString());
3422
3423            // Bring up the infamous App Not Responding dialog
3424            Message msg = Message.obtain();
3425            HashMap map = new HashMap();
3426            msg.what = SHOW_NOT_RESPONDING_MSG;
3427            msg.obj = map;
3428            map.put("app", app);
3429            if (activity != null) {
3430                map.put("activity", activity);
3431            }
3432
3433            mHandler.sendMessage(msg);
3434        }
3435    }
3436
3437    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3438        if (!mLaunchWarningShown) {
3439            mLaunchWarningShown = true;
3440            mHandler.post(new Runnable() {
3441                @Override
3442                public void run() {
3443                    synchronized (ActivityManagerService.this) {
3444                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3445                        d.show();
3446                        mHandler.postDelayed(new Runnable() {
3447                            @Override
3448                            public void run() {
3449                                synchronized (ActivityManagerService.this) {
3450                                    d.dismiss();
3451                                    mLaunchWarningShown = false;
3452                                }
3453                            }
3454                        }, 4000);
3455                    }
3456                }
3457            });
3458        }
3459    }
3460
3461    public boolean clearApplicationUserData(final String packageName,
3462            final IPackageDataObserver observer, int userId) {
3463        enforceNotIsolatedCaller("clearApplicationUserData");
3464        int uid = Binder.getCallingUid();
3465        int pid = Binder.getCallingPid();
3466        userId = handleIncomingUser(pid, uid,
3467                userId, false, true, "clearApplicationUserData", null);
3468        long callingId = Binder.clearCallingIdentity();
3469        try {
3470            IPackageManager pm = AppGlobals.getPackageManager();
3471            int pkgUid = -1;
3472            synchronized(this) {
3473                try {
3474                    pkgUid = pm.getPackageUid(packageName, userId);
3475                } catch (RemoteException e) {
3476                }
3477                if (pkgUid == -1) {
3478                    Slog.w(TAG, "Invalid packageName:" + packageName);
3479                    return false;
3480                }
3481                if (uid == pkgUid || checkComponentPermission(
3482                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3483                        pid, uid, -1, true)
3484                        == PackageManager.PERMISSION_GRANTED) {
3485                    forceStopPackageLocked(packageName, pkgUid);
3486                } else {
3487                    throw new SecurityException(pid+" does not have permission:"+
3488                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3489                                    "for process:"+packageName);
3490                }
3491            }
3492
3493            try {
3494                //clear application user data
3495                pm.clearApplicationUserData(packageName, observer, userId);
3496                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3497                        Uri.fromParts("package", packageName, null));
3498                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3499                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3500                        null, null, 0, null, null, null, false, false, userId);
3501            } catch (RemoteException e) {
3502            }
3503        } finally {
3504            Binder.restoreCallingIdentity(callingId);
3505        }
3506        return true;
3507    }
3508
3509    public void killBackgroundProcesses(final String packageName, int userId) {
3510        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3511                != PackageManager.PERMISSION_GRANTED &&
3512                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3513                        != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521
3522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3523                userId, true, true, "killBackgroundProcesses", null);
3524        long callingId = Binder.clearCallingIdentity();
3525        try {
3526            IPackageManager pm = AppGlobals.getPackageManager();
3527            synchronized(this) {
3528                int appId = -1;
3529                try {
3530                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3531                } catch (RemoteException e) {
3532                }
3533                if (appId == -1) {
3534                    Slog.w(TAG, "Invalid packageName: " + packageName);
3535                    return;
3536                }
3537                killPackageProcessesLocked(packageName, appId, userId,
3538                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3539            }
3540        } finally {
3541            Binder.restoreCallingIdentity(callingId);
3542        }
3543    }
3544
3545    public void killAllBackgroundProcesses() {
3546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3547                != PackageManager.PERMISSION_GRANTED) {
3548            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3549                    + Binder.getCallingPid()
3550                    + ", uid=" + Binder.getCallingUid()
3551                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3552            Slog.w(TAG, msg);
3553            throw new SecurityException(msg);
3554        }
3555
3556        long callingId = Binder.clearCallingIdentity();
3557        try {
3558            synchronized(this) {
3559                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3560                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3561                    final int NA = apps.size();
3562                    for (int ia=0; ia<NA; ia++) {
3563                        ProcessRecord app = apps.valueAt(ia);
3564                        if (app.persistent) {
3565                            // we don't kill persistent processes
3566                            continue;
3567                        }
3568                        if (app.removed) {
3569                            procs.add(app);
3570                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3571                            app.removed = true;
3572                            procs.add(app);
3573                        }
3574                    }
3575                }
3576
3577                int N = procs.size();
3578                for (int i=0; i<N; i++) {
3579                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3580                }
3581            }
3582        } finally {
3583            Binder.restoreCallingIdentity(callingId);
3584        }
3585    }
3586
3587    public void forceStopPackage(final String packageName, int userId) {
3588        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3589                != PackageManager.PERMISSION_GRANTED) {
3590            String msg = "Permission Denial: forceStopPackage() from pid="
3591                    + Binder.getCallingPid()
3592                    + ", uid=" + Binder.getCallingUid()
3593                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3594            Slog.w(TAG, msg);
3595            throw new SecurityException(msg);
3596        }
3597        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3598                userId, true, true, "forceStopPackage", null);
3599        long callingId = Binder.clearCallingIdentity();
3600        try {
3601            IPackageManager pm = AppGlobals.getPackageManager();
3602            synchronized(this) {
3603                int[] users = userId == UserHandle.USER_ALL
3604                        ? getUsersLocked() : new int[] { userId };
3605                for (int user : users) {
3606                    int pkgUid = -1;
3607                    try {
3608                        pkgUid = pm.getPackageUid(packageName, user);
3609                    } catch (RemoteException e) {
3610                    }
3611                    if (pkgUid == -1) {
3612                        Slog.w(TAG, "Invalid packageName: " + packageName);
3613                        continue;
3614                    }
3615                    try {
3616                        pm.setPackageStoppedState(packageName, true, user);
3617                    } catch (RemoteException e) {
3618                    } catch (IllegalArgumentException e) {
3619                        Slog.w(TAG, "Failed trying to unstop package "
3620                                + packageName + ": " + e);
3621                    }
3622                    if (isUserRunningLocked(user)) {
3623                        forceStopPackageLocked(packageName, pkgUid);
3624                    }
3625                }
3626            }
3627        } finally {
3628            Binder.restoreCallingIdentity(callingId);
3629        }
3630    }
3631
3632    /*
3633     * The pkg name and app id have to be specified.
3634     */
3635    public void killApplicationWithAppId(String pkg, int appid) {
3636        if (pkg == null) {
3637            return;
3638        }
3639        // Make sure the uid is valid.
3640        if (appid < 0) {
3641            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3642            return;
3643        }
3644        int callerUid = Binder.getCallingUid();
3645        // Only the system server can kill an application
3646        if (callerUid == Process.SYSTEM_UID) {
3647            // Post an aysnc message to kill the application
3648            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3649            msg.arg1 = appid;
3650            msg.arg2 = 0;
3651            msg.obj = pkg;
3652            mHandler.sendMessage(msg);
3653        } else {
3654            throw new SecurityException(callerUid + " cannot kill pkg: " +
3655                    pkg);
3656        }
3657    }
3658
3659    public void closeSystemDialogs(String reason) {
3660        enforceNotIsolatedCaller("closeSystemDialogs");
3661
3662        final int pid = Binder.getCallingPid();
3663        final int uid = Binder.getCallingUid();
3664        final long origId = Binder.clearCallingIdentity();
3665        try {
3666            synchronized (this) {
3667                // Only allow this from foreground processes, so that background
3668                // applications can't abuse it to prevent system UI from being shown.
3669                if (uid >= Process.FIRST_APPLICATION_UID) {
3670                    ProcessRecord proc;
3671                    synchronized (mPidsSelfLocked) {
3672                        proc = mPidsSelfLocked.get(pid);
3673                    }
3674                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3675                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3676                                + " from background process " + proc);
3677                        return;
3678                    }
3679                }
3680                closeSystemDialogsLocked(reason);
3681            }
3682        } finally {
3683            Binder.restoreCallingIdentity(origId);
3684        }
3685    }
3686
3687    void closeSystemDialogsLocked(String reason) {
3688        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3689        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3690        if (reason != null) {
3691            intent.putExtra("reason", reason);
3692        }
3693        mWindowManager.closeSystemDialogs(reason);
3694
3695        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3696            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3697            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3698                r.stack.finishActivityLocked(r, i,
3699                        Activity.RESULT_CANCELED, null, "close-sys", true);
3700            }
3701        }
3702
3703        broadcastIntentLocked(null, null, intent, null,
3704                null, 0, null, null, null, false, false, -1,
3705                Process.SYSTEM_UID, UserHandle.USER_ALL);
3706    }
3707
3708    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3709            throws RemoteException {
3710        enforceNotIsolatedCaller("getProcessMemoryInfo");
3711        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3712        for (int i=pids.length-1; i>=0; i--) {
3713            infos[i] = new Debug.MemoryInfo();
3714            Debug.getMemoryInfo(pids[i], infos[i]);
3715        }
3716        return infos;
3717    }
3718
3719    public long[] getProcessPss(int[] pids) throws RemoteException {
3720        enforceNotIsolatedCaller("getProcessPss");
3721        long[] pss = new long[pids.length];
3722        for (int i=pids.length-1; i>=0; i--) {
3723            pss[i] = Debug.getPss(pids[i]);
3724        }
3725        return pss;
3726    }
3727
3728    public void killApplicationProcess(String processName, int uid) {
3729        if (processName == null) {
3730            return;
3731        }
3732
3733        int callerUid = Binder.getCallingUid();
3734        // Only the system server can kill an application
3735        if (callerUid == Process.SYSTEM_UID) {
3736            synchronized (this) {
3737                ProcessRecord app = getProcessRecordLocked(processName, uid);
3738                if (app != null && app.thread != null) {
3739                    try {
3740                        app.thread.scheduleSuicide();
3741                    } catch (RemoteException e) {
3742                        // If the other end already died, then our work here is done.
3743                    }
3744                } else {
3745                    Slog.w(TAG, "Process/uid not found attempting kill of "
3746                            + processName + " / " + uid);
3747                }
3748            }
3749        } else {
3750            throw new SecurityException(callerUid + " cannot kill app process: " +
3751                    processName);
3752        }
3753    }
3754
3755    private void forceStopPackageLocked(final String packageName, int uid) {
3756        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3757                false, true, false, UserHandle.getUserId(uid));
3758        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3759                Uri.fromParts("package", packageName, null));
3760        if (!mProcessesReady) {
3761            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3762        }
3763        intent.putExtra(Intent.EXTRA_UID, uid);
3764        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3765        broadcastIntentLocked(null, null, intent,
3766                null, null, 0, null, null, null,
3767                false, false,
3768                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3769    }
3770
3771    private void forceStopUserLocked(int userId) {
3772        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3773        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3774        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3775        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3776        broadcastIntentLocked(null, null, intent,
3777                null, null, 0, null, null, null,
3778                false, false,
3779                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3780    }
3781
3782    private final boolean killPackageProcessesLocked(String packageName, int appId,
3783            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3784            boolean doit, boolean evenPersistent, String reason) {
3785        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3786
3787        // Remove all processes this package may have touched: all with the
3788        // same UID (except for the system or root user), and all whose name
3789        // matches the package name.
3790        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3791        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3792            final int NA = apps.size();
3793            for (int ia=0; ia<NA; ia++) {
3794                ProcessRecord app = apps.valueAt(ia);
3795                if (app.persistent && !evenPersistent) {
3796                    // we don't kill persistent processes
3797                    continue;
3798                }
3799                if (app.removed) {
3800                    if (doit) {
3801                        procs.add(app);
3802                    }
3803                    continue;
3804                }
3805
3806                // Skip process if it doesn't meet our oom adj requirement.
3807                if (app.setAdj < minOomAdj) {
3808                    continue;
3809                }
3810
3811                // If no package is specified, we call all processes under the
3812                // give user id.
3813                if (packageName == null) {
3814                    if (app.userId != userId) {
3815                        continue;
3816                    }
3817                // Package has been specified, we want to hit all processes
3818                // that match it.  We need to qualify this by the processes
3819                // that are running under the specified app and user ID.
3820                } else {
3821                    if (UserHandle.getAppId(app.uid) != appId) {
3822                        continue;
3823                    }
3824                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3825                        continue;
3826                    }
3827                    if (!app.pkgList.contains(packageName)) {
3828                        continue;
3829                    }
3830                }
3831
3832                // Process has passed all conditions, kill it!
3833                if (!doit) {
3834                    return true;
3835                }
3836                app.removed = true;
3837                procs.add(app);
3838            }
3839        }
3840
3841        int N = procs.size();
3842        for (int i=0; i<N; i++) {
3843            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3844        }
3845        return N > 0;
3846    }
3847
3848    private final boolean forceStopPackageLocked(String name, int appId,
3849            boolean callerWillRestart, boolean purgeCache, boolean doit,
3850            boolean evenPersistent, int userId) {
3851        int i;
3852        int N;
3853
3854        if (userId == UserHandle.USER_ALL && name == null) {
3855            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3856        }
3857
3858        if (appId < 0 && name != null) {
3859            try {
3860                appId = UserHandle.getAppId(
3861                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3862            } catch (RemoteException e) {
3863            }
3864        }
3865
3866        if (doit) {
3867            if (name != null) {
3868                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3869                        + " user=" + userId);
3870            } else {
3871                Slog.i(TAG, "Force stopping user " + userId);
3872            }
3873
3874            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3875            while (badApps.hasNext()) {
3876                SparseArray<Long> ba = badApps.next();
3877                for (i=ba.size()-1; i>=0; i--) {
3878                    boolean remove = false;
3879                    final int entUid = ba.keyAt(i);
3880                    if (name != null) {
3881                        if (userId == UserHandle.USER_ALL) {
3882                            if (UserHandle.getAppId(entUid) == appId) {
3883                                remove = true;
3884                            }
3885                        } else {
3886                            if (entUid == UserHandle.getUid(userId, appId)) {
3887                                remove = true;
3888                            }
3889                        }
3890                    } else if (UserHandle.getUserId(entUid) == userId) {
3891                        remove = true;
3892                    }
3893                    if (remove) {
3894                        ba.removeAt(i);
3895                    }
3896                }
3897                if (ba.size() == 0) {
3898                    badApps.remove();
3899                }
3900            }
3901        }
3902
3903        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3904                -100, callerWillRestart, false, doit, evenPersistent,
3905                name == null ? ("force stop user " + userId) : ("force stop " + name));
3906
3907        TaskRecord lastTask = null;
3908        for (i=0; i<mMainStack.mHistory.size(); i++) {
3909            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3910            final boolean samePackage = r.packageName.equals(name)
3911                    || (name == null && r.userId == userId);
3912            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3913                    && (samePackage || r.task == lastTask)
3914                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3915                if (!doit) {
3916                    if (r.finishing) {
3917                        // If this activity is just finishing, then it is not
3918                        // interesting as far as something to stop.
3919                        continue;
3920                    }
3921                    return true;
3922                }
3923                didSomething = true;
3924                Slog.i(TAG, "  Force finishing activity " + r);
3925                if (samePackage) {
3926                    if (r.app != null) {
3927                        r.app.removed = true;
3928                    }
3929                    r.app = null;
3930                }
3931                lastTask = r.task;
3932                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3933                        null, "force-stop", true)) {
3934                    i--;
3935                }
3936            }
3937        }
3938
3939        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3940            if (!doit) {
3941                return true;
3942            }
3943            didSomething = true;
3944        }
3945
3946        if (name == null) {
3947            // Remove all sticky broadcasts from this user.
3948            mStickyBroadcasts.remove(userId);
3949        }
3950
3951        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3952        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3953                userId, providers)) {
3954            if (!doit) {
3955                return true;
3956            }
3957            didSomething = true;
3958        }
3959        N = providers.size();
3960        for (i=0; i<N; i++) {
3961            removeDyingProviderLocked(null, providers.get(i), true);
3962        }
3963
3964        if (mIntentSenderRecords.size() > 0) {
3965            Iterator<WeakReference<PendingIntentRecord>> it
3966                    = mIntentSenderRecords.values().iterator();
3967            while (it.hasNext()) {
3968                WeakReference<PendingIntentRecord> wpir = it.next();
3969                if (wpir == null) {
3970                    it.remove();
3971                    continue;
3972                }
3973                PendingIntentRecord pir = wpir.get();
3974                if (pir == null) {
3975                    it.remove();
3976                    continue;
3977                }
3978                if (name == null) {
3979                    // Stopping user, remove all objects for the user.
3980                    if (pir.key.userId != userId) {
3981                        // Not the same user, skip it.
3982                        continue;
3983                    }
3984                } else {
3985                    if (UserHandle.getAppId(pir.uid) != appId) {
3986                        // Different app id, skip it.
3987                        continue;
3988                    }
3989                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3990                        // Different user, skip it.
3991                        continue;
3992                    }
3993                    if (!pir.key.packageName.equals(name)) {
3994                        // Different package, skip it.
3995                        continue;
3996                    }
3997                }
3998                if (!doit) {
3999                    return true;
4000                }
4001                didSomething = true;
4002                it.remove();
4003                pir.canceled = true;
4004                if (pir.key.activity != null) {
4005                    pir.key.activity.pendingResults.remove(pir.ref);
4006                }
4007            }
4008        }
4009
4010        if (doit) {
4011            if (purgeCache && name != null) {
4012                AttributeCache ac = AttributeCache.instance();
4013                if (ac != null) {
4014                    ac.removePackage(name);
4015                }
4016            }
4017            if (mBooted) {
4018                mMainStack.resumeTopActivityLocked(null);
4019                mMainStack.scheduleIdleLocked();
4020            }
4021        }
4022
4023        return didSomething;
4024    }
4025
4026    private final boolean removeProcessLocked(ProcessRecord app,
4027            boolean callerWillRestart, boolean allowRestart, String reason) {
4028        final String name = app.processName;
4029        final int uid = app.uid;
4030        if (DEBUG_PROCESSES) Slog.d(
4031            TAG, "Force removing proc " + app.toShortString() + " (" + name
4032            + "/" + uid + ")");
4033
4034        mProcessNames.remove(name, uid);
4035        mIsolatedProcesses.remove(app.uid);
4036        if (mHeavyWeightProcess == app) {
4037            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4038                    mHeavyWeightProcess.userId, 0));
4039            mHeavyWeightProcess = null;
4040        }
4041        boolean needRestart = false;
4042        if (app.pid > 0 && app.pid != MY_PID) {
4043            int pid = app.pid;
4044            synchronized (mPidsSelfLocked) {
4045                mPidsSelfLocked.remove(pid);
4046                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4047            }
4048            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4049            handleAppDiedLocked(app, true, allowRestart);
4050            mLruProcesses.remove(app);
4051            Process.killProcessQuiet(pid);
4052
4053            if (app.persistent && !app.isolated) {
4054                if (!callerWillRestart) {
4055                    addAppLocked(app.info, false);
4056                } else {
4057                    needRestart = true;
4058                }
4059            }
4060        } else {
4061            mRemovedProcesses.add(app);
4062        }
4063
4064        return needRestart;
4065    }
4066
4067    private final void processStartTimedOutLocked(ProcessRecord app) {
4068        final int pid = app.pid;
4069        boolean gone = false;
4070        synchronized (mPidsSelfLocked) {
4071            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4072            if (knownApp != null && knownApp.thread == null) {
4073                mPidsSelfLocked.remove(pid);
4074                gone = true;
4075            }
4076        }
4077
4078        if (gone) {
4079            Slog.w(TAG, "Process " + app + " failed to attach");
4080            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4081                    app.processName);
4082            mProcessNames.remove(app.processName, app.uid);
4083            mIsolatedProcesses.remove(app.uid);
4084            if (mHeavyWeightProcess == app) {
4085                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4086                        mHeavyWeightProcess.userId, 0));
4087                mHeavyWeightProcess = null;
4088            }
4089            // Take care of any launching providers waiting for this process.
4090            checkAppInLaunchingProvidersLocked(app, true);
4091            // Take care of any services that are waiting for the process.
4092            mServices.processStartTimedOutLocked(app);
4093            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4094                    app.processName, app.setAdj, "start timeout");
4095            Process.killProcessQuiet(pid);
4096            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4097                Slog.w(TAG, "Unattached app died before backup, skipping");
4098                try {
4099                    IBackupManager bm = IBackupManager.Stub.asInterface(
4100                            ServiceManager.getService(Context.BACKUP_SERVICE));
4101                    bm.agentDisconnected(app.info.packageName);
4102                } catch (RemoteException e) {
4103                    // Can't happen; the backup manager is local
4104                }
4105            }
4106            if (isPendingBroadcastProcessLocked(pid)) {
4107                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4108                skipPendingBroadcastLocked(pid);
4109            }
4110        } else {
4111            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4112        }
4113    }
4114
4115    private final boolean attachApplicationLocked(IApplicationThread thread,
4116            int pid) {
4117
4118        // Find the application record that is being attached...  either via
4119        // the pid if we are running in multiple processes, or just pull the
4120        // next app record if we are emulating process with anonymous threads.
4121        ProcessRecord app;
4122        if (pid != MY_PID && pid >= 0) {
4123            synchronized (mPidsSelfLocked) {
4124                app = mPidsSelfLocked.get(pid);
4125            }
4126        } else {
4127            app = null;
4128        }
4129
4130        if (app == null) {
4131            Slog.w(TAG, "No pending application record for pid " + pid
4132                    + " (IApplicationThread " + thread + "); dropping process");
4133            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4134            if (pid > 0 && pid != MY_PID) {
4135                Process.killProcessQuiet(pid);
4136            } else {
4137                try {
4138                    thread.scheduleExit();
4139                } catch (Exception e) {
4140                    // Ignore exceptions.
4141                }
4142            }
4143            return false;
4144        }
4145
4146        // If this application record is still attached to a previous
4147        // process, clean it up now.
4148        if (app.thread != null) {
4149            handleAppDiedLocked(app, true, true);
4150        }
4151
4152        // Tell the process all about itself.
4153
4154        if (localLOGV) Slog.v(
4155                TAG, "Binding process pid " + pid + " to record " + app);
4156
4157        String processName = app.processName;
4158        try {
4159            AppDeathRecipient adr = new AppDeathRecipient(
4160                    app, pid, thread);
4161            thread.asBinder().linkToDeath(adr, 0);
4162            app.deathRecipient = adr;
4163        } catch (RemoteException e) {
4164            app.resetPackageList();
4165            startProcessLocked(app, "link fail", processName);
4166            return false;
4167        }
4168
4169        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4170
4171        app.thread = thread;
4172        app.curAdj = app.setAdj = -100;
4173        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4174        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4175        app.forcingToForeground = null;
4176        app.foregroundServices = false;
4177        app.hasShownUi = false;
4178        app.debugging = false;
4179
4180        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4181
4182        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4183        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4184
4185        if (!normalMode) {
4186            Slog.i(TAG, "Launching preboot mode app: " + app);
4187        }
4188
4189        if (localLOGV) Slog.v(
4190            TAG, "New app record " + app
4191            + " thread=" + thread.asBinder() + " pid=" + pid);
4192        try {
4193            int testMode = IApplicationThread.DEBUG_OFF;
4194            if (mDebugApp != null && mDebugApp.equals(processName)) {
4195                testMode = mWaitForDebugger
4196                    ? IApplicationThread.DEBUG_WAIT
4197                    : IApplicationThread.DEBUG_ON;
4198                app.debugging = true;
4199                if (mDebugTransient) {
4200                    mDebugApp = mOrigDebugApp;
4201                    mWaitForDebugger = mOrigWaitForDebugger;
4202                }
4203            }
4204            String profileFile = app.instrumentationProfileFile;
4205            ParcelFileDescriptor profileFd = null;
4206            boolean profileAutoStop = false;
4207            if (mProfileApp != null && mProfileApp.equals(processName)) {
4208                mProfileProc = app;
4209                profileFile = mProfileFile;
4210                profileFd = mProfileFd;
4211                profileAutoStop = mAutoStopProfiler;
4212            }
4213            boolean enableOpenGlTrace = false;
4214            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4215                enableOpenGlTrace = true;
4216                mOpenGlTraceApp = null;
4217            }
4218
4219            // If the app is being launched for restore or full backup, set it up specially
4220            boolean isRestrictedBackupMode = false;
4221            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4222                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4223                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4224                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4225            }
4226
4227            ensurePackageDexOpt(app.instrumentationInfo != null
4228                    ? app.instrumentationInfo.packageName
4229                    : app.info.packageName);
4230            if (app.instrumentationClass != null) {
4231                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4232            }
4233            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4234                    + processName + " with config " + mConfiguration);
4235            ApplicationInfo appInfo = app.instrumentationInfo != null
4236                    ? app.instrumentationInfo : app.info;
4237            app.compat = compatibilityInfoForPackageLocked(appInfo);
4238            if (profileFd != null) {
4239                profileFd = profileFd.dup();
4240            }
4241            thread.bindApplication(processName, appInfo, providers,
4242                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4243                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4244                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4245                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4246                    mCoreSettingsObserver.getCoreSettingsLocked());
4247            updateLruProcessLocked(app, false, true);
4248            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4249        } catch (Exception e) {
4250            // todo: Yikes!  What should we do?  For now we will try to
4251            // start another process, but that could easily get us in
4252            // an infinite loop of restarting processes...
4253            Slog.w(TAG, "Exception thrown during bind!", e);
4254
4255            app.resetPackageList();
4256            app.unlinkDeathRecipient();
4257            startProcessLocked(app, "bind fail", processName);
4258            return false;
4259        }
4260
4261        // Remove this record from the list of starting applications.
4262        mPersistentStartingProcesses.remove(app);
4263        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4264                "Attach application locked removing on hold: " + app);
4265        mProcessesOnHold.remove(app);
4266
4267        boolean badApp = false;
4268        boolean didSomething = false;
4269
4270        // See if the top visible activity is waiting to run in this process...
4271        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4272        if (hr != null && normalMode) {
4273            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4274                    && processName.equals(hr.processName)) {
4275                try {
4276                    if (mHeadless) {
4277                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4278                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4279                        didSomething = true;
4280                    }
4281                } catch (Exception e) {
4282                    Slog.w(TAG, "Exception in new application when starting activity "
4283                          + hr.intent.getComponent().flattenToShortString(), e);
4284                    badApp = true;
4285                }
4286            } else {
4287                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4288            }
4289        }
4290
4291        // Find any services that should be running in this process...
4292        if (!badApp) {
4293            try {
4294                didSomething |= mServices.attachApplicationLocked(app, processName);
4295            } catch (Exception e) {
4296                badApp = true;
4297            }
4298        }
4299
4300        // Check if a next-broadcast receiver is in this process...
4301        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4302            try {
4303                didSomething = sendPendingBroadcastsLocked(app);
4304            } catch (Exception e) {
4305                // If the app died trying to launch the receiver we declare it 'bad'
4306                badApp = true;
4307            }
4308        }
4309
4310        // Check whether the next backup agent is in this process...
4311        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4312            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4313            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4314            try {
4315                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4316                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4317                        mBackupTarget.backupMode);
4318            } catch (Exception e) {
4319                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4320                e.printStackTrace();
4321            }
4322        }
4323
4324        if (badApp) {
4325            // todo: Also need to kill application to deal with all
4326            // kinds of exceptions.
4327            handleAppDiedLocked(app, false, true);
4328            return false;
4329        }
4330
4331        if (!didSomething) {
4332            updateOomAdjLocked();
4333        }
4334
4335        return true;
4336    }
4337
4338    public final void attachApplication(IApplicationThread thread) {
4339        synchronized (this) {
4340            int callingPid = Binder.getCallingPid();
4341            final long origId = Binder.clearCallingIdentity();
4342            attachApplicationLocked(thread, callingPid);
4343            Binder.restoreCallingIdentity(origId);
4344        }
4345    }
4346
4347    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4348        final long origId = Binder.clearCallingIdentity();
4349        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4350        if (stopProfiling) {
4351            synchronized (this) {
4352                if (mProfileProc == r.app) {
4353                    if (mProfileFd != null) {
4354                        try {
4355                            mProfileFd.close();
4356                        } catch (IOException e) {
4357                        }
4358                        clearProfilerLocked();
4359                    }
4360                }
4361            }
4362        }
4363        Binder.restoreCallingIdentity(origId);
4364    }
4365
4366    void enableScreenAfterBoot() {
4367        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4368                SystemClock.uptimeMillis());
4369        mWindowManager.enableScreenAfterBoot();
4370
4371        synchronized (this) {
4372            updateEventDispatchingLocked();
4373        }
4374    }
4375
4376    public void showBootMessage(final CharSequence msg, final boolean always) {
4377        enforceNotIsolatedCaller("showBootMessage");
4378        mWindowManager.showBootMessage(msg, always);
4379    }
4380
4381    public void dismissKeyguardOnNextActivity() {
4382        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4383        final long token = Binder.clearCallingIdentity();
4384        try {
4385            synchronized (this) {
4386                if (mLockScreenShown) {
4387                    mLockScreenShown = false;
4388                    comeOutOfSleepIfNeededLocked();
4389                }
4390                mMainStack.dismissKeyguardOnNextActivityLocked();
4391            }
4392        } finally {
4393            Binder.restoreCallingIdentity(token);
4394        }
4395    }
4396
4397    final void finishBooting() {
4398        IntentFilter pkgFilter = new IntentFilter();
4399        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4400        pkgFilter.addDataScheme("package");
4401        mContext.registerReceiver(new BroadcastReceiver() {
4402            @Override
4403            public void onReceive(Context context, Intent intent) {
4404                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4405                if (pkgs != null) {
4406                    for (String pkg : pkgs) {
4407                        synchronized (ActivityManagerService.this) {
4408                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4409                                setResultCode(Activity.RESULT_OK);
4410                                return;
4411                            }
4412                        }
4413                    }
4414                }
4415            }
4416        }, pkgFilter);
4417
4418        synchronized (this) {
4419            // Ensure that any processes we had put on hold are now started
4420            // up.
4421            final int NP = mProcessesOnHold.size();
4422            if (NP > 0) {
4423                ArrayList<ProcessRecord> procs =
4424                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4425                for (int ip=0; ip<NP; ip++) {
4426                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4427                            + procs.get(ip));
4428                    startProcessLocked(procs.get(ip), "on-hold", null);
4429                }
4430            }
4431
4432            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4433                // Start looking for apps that are abusing wake locks.
4434                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4435                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4436                // Tell anyone interested that we are done booting!
4437                SystemProperties.set("sys.boot_completed", "1");
4438                SystemProperties.set("dev.bootcomplete", "1");
4439                for (int i=0; i<mStartedUsers.size(); i++) {
4440                    UserStartedState uss = mStartedUsers.valueAt(i);
4441                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4442                        uss.mState = UserStartedState.STATE_RUNNING;
4443                        final int userId = mStartedUsers.keyAt(i);
4444                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4445                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4446                        broadcastIntentLocked(null, null, intent,
4447                                null, null, 0, null, null,
4448                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4449                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4450                    }
4451                }
4452            }
4453        }
4454    }
4455
4456    final void ensureBootCompleted() {
4457        boolean booting;
4458        boolean enableScreen;
4459        synchronized (this) {
4460            booting = mBooting;
4461            mBooting = false;
4462            enableScreen = !mBooted;
4463            mBooted = true;
4464        }
4465
4466        if (booting) {
4467            finishBooting();
4468        }
4469
4470        if (enableScreen) {
4471            enableScreenAfterBoot();
4472        }
4473    }
4474
4475    public final void activityResumed(IBinder token) {
4476        final long origId = Binder.clearCallingIdentity();
4477        mMainStack.activityResumed(token);
4478        Binder.restoreCallingIdentity(origId);
4479    }
4480
4481    public final void activityPaused(IBinder token) {
4482        final long origId = Binder.clearCallingIdentity();
4483        mMainStack.activityPaused(token, false);
4484        Binder.restoreCallingIdentity(origId);
4485    }
4486
4487    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4488            CharSequence description) {
4489        if (localLOGV) Slog.v(
4490            TAG, "Activity stopped: token=" + token);
4491
4492        // Refuse possible leaked file descriptors
4493        if (icicle != null && icicle.hasFileDescriptors()) {
4494            throw new IllegalArgumentException("File descriptors passed in Bundle");
4495        }
4496
4497        ActivityRecord r = null;
4498
4499        final long origId = Binder.clearCallingIdentity();
4500
4501        synchronized (this) {
4502            r = mMainStack.isInStackLocked(token);
4503            if (r != null) {
4504                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4505            }
4506        }
4507
4508        if (r != null) {
4509            sendPendingThumbnail(r, null, null, null, false);
4510        }
4511
4512        trimApplications();
4513
4514        Binder.restoreCallingIdentity(origId);
4515    }
4516
4517    public final void activityDestroyed(IBinder token) {
4518        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4519        mMainStack.activityDestroyed(token);
4520    }
4521
4522    public String getCallingPackage(IBinder token) {
4523        synchronized (this) {
4524            ActivityRecord r = getCallingRecordLocked(token);
4525            return r != null && r.app != null ? r.info.packageName : null;
4526        }
4527    }
4528
4529    public ComponentName getCallingActivity(IBinder token) {
4530        synchronized (this) {
4531            ActivityRecord r = getCallingRecordLocked(token);
4532            return r != null ? r.intent.getComponent() : null;
4533        }
4534    }
4535
4536    private ActivityRecord getCallingRecordLocked(IBinder token) {
4537        ActivityRecord r = mMainStack.isInStackLocked(token);
4538        if (r == null) {
4539            return null;
4540        }
4541        return r.resultTo;
4542    }
4543
4544    public ComponentName getActivityClassForToken(IBinder token) {
4545        synchronized(this) {
4546            ActivityRecord r = mMainStack.isInStackLocked(token);
4547            if (r == null) {
4548                return null;
4549            }
4550            return r.intent.getComponent();
4551        }
4552    }
4553
4554    public String getPackageForToken(IBinder token) {
4555        synchronized(this) {
4556            ActivityRecord r = mMainStack.isInStackLocked(token);
4557            if (r == null) {
4558                return null;
4559            }
4560            return r.packageName;
4561        }
4562    }
4563
4564    public IIntentSender getIntentSender(int type,
4565            String packageName, IBinder token, String resultWho,
4566            int requestCode, Intent[] intents, String[] resolvedTypes,
4567            int flags, Bundle options, int userId) {
4568        enforceNotIsolatedCaller("getIntentSender");
4569        // Refuse possible leaked file descriptors
4570        if (intents != null) {
4571            if (intents.length < 1) {
4572                throw new IllegalArgumentException("Intents array length must be >= 1");
4573            }
4574            for (int i=0; i<intents.length; i++) {
4575                Intent intent = intents[i];
4576                if (intent != null) {
4577                    if (intent.hasFileDescriptors()) {
4578                        throw new IllegalArgumentException("File descriptors passed in Intent");
4579                    }
4580                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4581                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4582                        throw new IllegalArgumentException(
4583                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4584                    }
4585                    intents[i] = new Intent(intent);
4586                }
4587            }
4588            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4589                throw new IllegalArgumentException(
4590                        "Intent array length does not match resolvedTypes length");
4591            }
4592        }
4593        if (options != null) {
4594            if (options.hasFileDescriptors()) {
4595                throw new IllegalArgumentException("File descriptors passed in options");
4596            }
4597        }
4598
4599        synchronized(this) {
4600            int callingUid = Binder.getCallingUid();
4601            int origUserId = userId;
4602            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4603                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4604                    "getIntentSender", null);
4605            if (origUserId == UserHandle.USER_CURRENT) {
4606                // We don't want to evaluate this until the pending intent is
4607                // actually executed.  However, we do want to always do the
4608                // security checking for it above.
4609                userId = UserHandle.USER_CURRENT;
4610            }
4611            try {
4612                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4613                    int uid = AppGlobals.getPackageManager()
4614                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4615                    if (!UserHandle.isSameApp(callingUid, uid)) {
4616                        String msg = "Permission Denial: getIntentSender() from pid="
4617                            + Binder.getCallingPid()
4618                            + ", uid=" + Binder.getCallingUid()
4619                            + ", (need uid=" + uid + ")"
4620                            + " is not allowed to send as package " + packageName;
4621                        Slog.w(TAG, msg);
4622                        throw new SecurityException(msg);
4623                    }
4624                }
4625
4626                return getIntentSenderLocked(type, packageName, callingUid, userId,
4627                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4628
4629            } catch (RemoteException e) {
4630                throw new SecurityException(e);
4631            }
4632        }
4633    }
4634
4635    IIntentSender getIntentSenderLocked(int type, String packageName,
4636            int callingUid, int userId, IBinder token, String resultWho,
4637            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4638            Bundle options) {
4639        if (DEBUG_MU)
4640            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4641        ActivityRecord activity = null;
4642        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4643            activity = mMainStack.isInStackLocked(token);
4644            if (activity == null) {
4645                return null;
4646            }
4647            if (activity.finishing) {
4648                return null;
4649            }
4650        }
4651
4652        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4653        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4654        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4655        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4656                |PendingIntent.FLAG_UPDATE_CURRENT);
4657
4658        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4659                type, packageName, activity, resultWho,
4660                requestCode, intents, resolvedTypes, flags, options, userId);
4661        WeakReference<PendingIntentRecord> ref;
4662        ref = mIntentSenderRecords.get(key);
4663        PendingIntentRecord rec = ref != null ? ref.get() : null;
4664        if (rec != null) {
4665            if (!cancelCurrent) {
4666                if (updateCurrent) {
4667                    if (rec.key.requestIntent != null) {
4668                        rec.key.requestIntent.replaceExtras(intents != null ?
4669                                intents[intents.length - 1] : null);
4670                    }
4671                    if (intents != null) {
4672                        intents[intents.length-1] = rec.key.requestIntent;
4673                        rec.key.allIntents = intents;
4674                        rec.key.allResolvedTypes = resolvedTypes;
4675                    } else {
4676                        rec.key.allIntents = null;
4677                        rec.key.allResolvedTypes = null;
4678                    }
4679                }
4680                return rec;
4681            }
4682            rec.canceled = true;
4683            mIntentSenderRecords.remove(key);
4684        }
4685        if (noCreate) {
4686            return rec;
4687        }
4688        rec = new PendingIntentRecord(this, key, callingUid);
4689        mIntentSenderRecords.put(key, rec.ref);
4690        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4691            if (activity.pendingResults == null) {
4692                activity.pendingResults
4693                        = new HashSet<WeakReference<PendingIntentRecord>>();
4694            }
4695            activity.pendingResults.add(rec.ref);
4696        }
4697        return rec;
4698    }
4699
4700    public void cancelIntentSender(IIntentSender sender) {
4701        if (!(sender instanceof PendingIntentRecord)) {
4702            return;
4703        }
4704        synchronized(this) {
4705            PendingIntentRecord rec = (PendingIntentRecord)sender;
4706            try {
4707                int uid = AppGlobals.getPackageManager()
4708                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4709                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4710                    String msg = "Permission Denial: cancelIntentSender() from pid="
4711                        + Binder.getCallingPid()
4712                        + ", uid=" + Binder.getCallingUid()
4713                        + " is not allowed to cancel packges "
4714                        + rec.key.packageName;
4715                    Slog.w(TAG, msg);
4716                    throw new SecurityException(msg);
4717                }
4718            } catch (RemoteException e) {
4719                throw new SecurityException(e);
4720            }
4721            cancelIntentSenderLocked(rec, true);
4722        }
4723    }
4724
4725    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4726        rec.canceled = true;
4727        mIntentSenderRecords.remove(rec.key);
4728        if (cleanActivity && rec.key.activity != null) {
4729            rec.key.activity.pendingResults.remove(rec.ref);
4730        }
4731    }
4732
4733    public String getPackageForIntentSender(IIntentSender pendingResult) {
4734        if (!(pendingResult instanceof PendingIntentRecord)) {
4735            return null;
4736        }
4737        try {
4738            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4739            return res.key.packageName;
4740        } catch (ClassCastException e) {
4741        }
4742        return null;
4743    }
4744
4745    public int getUidForIntentSender(IIntentSender sender) {
4746        if (sender instanceof PendingIntentRecord) {
4747            try {
4748                PendingIntentRecord res = (PendingIntentRecord)sender;
4749                return res.uid;
4750            } catch (ClassCastException e) {
4751            }
4752        }
4753        return -1;
4754    }
4755
4756    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4757        if (!(pendingResult instanceof PendingIntentRecord)) {
4758            return false;
4759        }
4760        try {
4761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4762            if (res.key.allIntents == null) {
4763                return false;
4764            }
4765            for (int i=0; i<res.key.allIntents.length; i++) {
4766                Intent intent = res.key.allIntents[i];
4767                if (intent.getPackage() != null && intent.getComponent() != null) {
4768                    return false;
4769                }
4770            }
4771            return true;
4772        } catch (ClassCastException e) {
4773        }
4774        return false;
4775    }
4776
4777    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4778        if (!(pendingResult instanceof PendingIntentRecord)) {
4779            return false;
4780        }
4781        try {
4782            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4783            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4784                return true;
4785            }
4786            return false;
4787        } catch (ClassCastException e) {
4788        }
4789        return false;
4790    }
4791
4792    public void setProcessLimit(int max) {
4793        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4794                "setProcessLimit()");
4795        synchronized (this) {
4796            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4797            mProcessLimitOverride = max;
4798        }
4799        trimApplications();
4800    }
4801
4802    public int getProcessLimit() {
4803        synchronized (this) {
4804            return mProcessLimitOverride;
4805        }
4806    }
4807
4808    void foregroundTokenDied(ForegroundToken token) {
4809        synchronized (ActivityManagerService.this) {
4810            synchronized (mPidsSelfLocked) {
4811                ForegroundToken cur
4812                    = mForegroundProcesses.get(token.pid);
4813                if (cur != token) {
4814                    return;
4815                }
4816                mForegroundProcesses.remove(token.pid);
4817                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4818                if (pr == null) {
4819                    return;
4820                }
4821                pr.forcingToForeground = null;
4822                pr.foregroundServices = false;
4823            }
4824            updateOomAdjLocked();
4825        }
4826    }
4827
4828    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4829        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4830                "setProcessForeground()");
4831        synchronized(this) {
4832            boolean changed = false;
4833
4834            synchronized (mPidsSelfLocked) {
4835                ProcessRecord pr = mPidsSelfLocked.get(pid);
4836                if (pr == null && isForeground) {
4837                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4838                    return;
4839                }
4840                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4841                if (oldToken != null) {
4842                    oldToken.token.unlinkToDeath(oldToken, 0);
4843                    mForegroundProcesses.remove(pid);
4844                    if (pr != null) {
4845                        pr.forcingToForeground = null;
4846                    }
4847                    changed = true;
4848                }
4849                if (isForeground && token != null) {
4850                    ForegroundToken newToken = new ForegroundToken() {
4851                        public void binderDied() {
4852                            foregroundTokenDied(this);
4853                        }
4854                    };
4855                    newToken.pid = pid;
4856                    newToken.token = token;
4857                    try {
4858                        token.linkToDeath(newToken, 0);
4859                        mForegroundProcesses.put(pid, newToken);
4860                        pr.forcingToForeground = token;
4861                        changed = true;
4862                    } catch (RemoteException e) {
4863                        // If the process died while doing this, we will later
4864                        // do the cleanup with the process death link.
4865                    }
4866                }
4867            }
4868
4869            if (changed) {
4870                updateOomAdjLocked();
4871            }
4872        }
4873    }
4874
4875    // =========================================================
4876    // PERMISSIONS
4877    // =========================================================
4878
4879    static class PermissionController extends IPermissionController.Stub {
4880        ActivityManagerService mActivityManagerService;
4881        PermissionController(ActivityManagerService activityManagerService) {
4882            mActivityManagerService = activityManagerService;
4883        }
4884
4885        public boolean checkPermission(String permission, int pid, int uid) {
4886            return mActivityManagerService.checkPermission(permission, pid,
4887                    uid) == PackageManager.PERMISSION_GRANTED;
4888        }
4889    }
4890
4891    /**
4892     * This can be called with or without the global lock held.
4893     */
4894    int checkComponentPermission(String permission, int pid, int uid,
4895            int owningUid, boolean exported) {
4896        // We might be performing an operation on behalf of an indirect binder
4897        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4898        // client identity accordingly before proceeding.
4899        Identity tlsIdentity = sCallerIdentity.get();
4900        if (tlsIdentity != null) {
4901            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4902                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4903            uid = tlsIdentity.uid;
4904            pid = tlsIdentity.pid;
4905        }
4906
4907        if (pid == MY_PID) {
4908            return PackageManager.PERMISSION_GRANTED;
4909        }
4910
4911        return ActivityManager.checkComponentPermission(permission, uid,
4912                owningUid, exported);
4913    }
4914
4915    /**
4916     * As the only public entry point for permissions checking, this method
4917     * can enforce the semantic that requesting a check on a null global
4918     * permission is automatically denied.  (Internally a null permission
4919     * string is used when calling {@link #checkComponentPermission} in cases
4920     * when only uid-based security is needed.)
4921     *
4922     * This can be called with or without the global lock held.
4923     */
4924    public int checkPermission(String permission, int pid, int uid) {
4925        if (permission == null) {
4926            return PackageManager.PERMISSION_DENIED;
4927        }
4928        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4929    }
4930
4931    /**
4932     * Binder IPC calls go through the public entry point.
4933     * This can be called with or without the global lock held.
4934     */
4935    int checkCallingPermission(String permission) {
4936        return checkPermission(permission,
4937                Binder.getCallingPid(),
4938                UserHandle.getAppId(Binder.getCallingUid()));
4939    }
4940
4941    /**
4942     * This can be called with or without the global lock held.
4943     */
4944    void enforceCallingPermission(String permission, String func) {
4945        if (checkCallingPermission(permission)
4946                == PackageManager.PERMISSION_GRANTED) {
4947            return;
4948        }
4949
4950        String msg = "Permission Denial: " + func + " from pid="
4951                + Binder.getCallingPid()
4952                + ", uid=" + Binder.getCallingUid()
4953                + " requires " + permission;
4954        Slog.w(TAG, msg);
4955        throw new SecurityException(msg);
4956    }
4957
4958    /**
4959     * Determine if UID is holding permissions required to access {@link Uri} in
4960     * the given {@link ProviderInfo}. Final permission checking is always done
4961     * in {@link ContentProvider}.
4962     */
4963    private final boolean checkHoldingPermissionsLocked(
4964            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4965        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4966                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4967
4968        if (pi.applicationInfo.uid == uid) {
4969            return true;
4970        } else if (!pi.exported) {
4971            return false;
4972        }
4973
4974        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4975        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4976        try {
4977            // check if target holds top-level <provider> permissions
4978            if (!readMet && pi.readPermission != null
4979                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4980                readMet = true;
4981            }
4982            if (!writeMet && pi.writePermission != null
4983                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4984                writeMet = true;
4985            }
4986
4987            // track if unprotected read/write is allowed; any denied
4988            // <path-permission> below removes this ability
4989            boolean allowDefaultRead = pi.readPermission == null;
4990            boolean allowDefaultWrite = pi.writePermission == null;
4991
4992            // check if target holds any <path-permission> that match uri
4993            final PathPermission[] pps = pi.pathPermissions;
4994            if (pps != null) {
4995                final String path = uri.getPath();
4996                int i = pps.length;
4997                while (i > 0 && (!readMet || !writeMet)) {
4998                    i--;
4999                    PathPermission pp = pps[i];
5000                    if (pp.match(path)) {
5001                        if (!readMet) {
5002                            final String pprperm = pp.getReadPermission();
5003                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5004                                    + pprperm + " for " + pp.getPath()
5005                                    + ": match=" + pp.match(path)
5006                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5007                            if (pprperm != null) {
5008                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5009                                    readMet = true;
5010                                } else {
5011                                    allowDefaultRead = false;
5012                                }
5013                            }
5014                        }
5015                        if (!writeMet) {
5016                            final String ppwperm = pp.getWritePermission();
5017                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5018                                    + ppwperm + " for " + pp.getPath()
5019                                    + ": match=" + pp.match(path)
5020                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5021                            if (ppwperm != null) {
5022                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5023                                    writeMet = true;
5024                                } else {
5025                                    allowDefaultWrite = false;
5026                                }
5027                            }
5028                        }
5029                    }
5030                }
5031            }
5032
5033            // grant unprotected <provider> read/write, if not blocked by
5034            // <path-permission> above
5035            if (allowDefaultRead) readMet = true;
5036            if (allowDefaultWrite) writeMet = true;
5037
5038        } catch (RemoteException e) {
5039            return false;
5040        }
5041
5042        return readMet && writeMet;
5043    }
5044
5045    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5046            int modeFlags) {
5047        // Root gets to do everything.
5048        if (uid == 0) {
5049            return true;
5050        }
5051        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5052        if (perms == null) return false;
5053        UriPermission perm = perms.get(uri);
5054        if (perm == null) return false;
5055        return (modeFlags&perm.modeFlags) == modeFlags;
5056    }
5057
5058    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5059        enforceNotIsolatedCaller("checkUriPermission");
5060
5061        // Another redirected-binder-call permissions check as in
5062        // {@link checkComponentPermission}.
5063        Identity tlsIdentity = sCallerIdentity.get();
5064        if (tlsIdentity != null) {
5065            uid = tlsIdentity.uid;
5066            pid = tlsIdentity.pid;
5067        }
5068
5069        // Our own process gets to do everything.
5070        if (pid == MY_PID) {
5071            return PackageManager.PERMISSION_GRANTED;
5072        }
5073        synchronized(this) {
5074            return checkUriPermissionLocked(uri, uid, modeFlags)
5075                    ? PackageManager.PERMISSION_GRANTED
5076                    : PackageManager.PERMISSION_DENIED;
5077        }
5078    }
5079
5080    /**
5081     * Check if the targetPkg can be granted permission to access uri by
5082     * the callingUid using the given modeFlags.  Throws a security exception
5083     * if callingUid is not allowed to do this.  Returns the uid of the target
5084     * if the URI permission grant should be performed; returns -1 if it is not
5085     * needed (for example targetPkg already has permission to access the URI).
5086     * If you already know the uid of the target, you can supply it in
5087     * lastTargetUid else set that to -1.
5088     */
5089    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5090            Uri uri, int modeFlags, int lastTargetUid) {
5091        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5092                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5093        if (modeFlags == 0) {
5094            return -1;
5095        }
5096
5097        if (targetPkg != null) {
5098            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5099                    "Checking grant " + targetPkg + " permission to " + uri);
5100        }
5101
5102        final IPackageManager pm = AppGlobals.getPackageManager();
5103
5104        // If this is not a content: uri, we can't do anything with it.
5105        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5106            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5107                    "Can't grant URI permission for non-content URI: " + uri);
5108            return -1;
5109        }
5110
5111        String name = uri.getAuthority();
5112        ProviderInfo pi = null;
5113        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5114                UserHandle.getUserId(callingUid));
5115        if (cpr != null) {
5116            pi = cpr.info;
5117        } else {
5118            try {
5119                pi = pm.resolveContentProvider(name,
5120                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5121                        UserHandle.getUserId(callingUid));
5122            } catch (RemoteException ex) {
5123            }
5124        }
5125        if (pi == null) {
5126            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5127            return -1;
5128        }
5129
5130        int targetUid = lastTargetUid;
5131        if (targetUid < 0 && targetPkg != null) {
5132            try {
5133                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5134                if (targetUid < 0) {
5135                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5136                            "Can't grant URI permission no uid for: " + targetPkg);
5137                    return -1;
5138                }
5139            } catch (RemoteException ex) {
5140                return -1;
5141            }
5142        }
5143
5144        if (targetUid >= 0) {
5145            // First...  does the target actually need this permission?
5146            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5147                // No need to grant the target this permission.
5148                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5149                        "Target " + targetPkg + " already has full permission to " + uri);
5150                return -1;
5151            }
5152        } else {
5153            // First...  there is no target package, so can anyone access it?
5154            boolean allowed = pi.exported;
5155            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5156                if (pi.readPermission != null) {
5157                    allowed = false;
5158                }
5159            }
5160            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5161                if (pi.writePermission != null) {
5162                    allowed = false;
5163                }
5164            }
5165            if (allowed) {
5166                return -1;
5167            }
5168        }
5169
5170        // Second...  is the provider allowing granting of URI permissions?
5171        if (!pi.grantUriPermissions) {
5172            throw new SecurityException("Provider " + pi.packageName
5173                    + "/" + pi.name
5174                    + " does not allow granting of Uri permissions (uri "
5175                    + uri + ")");
5176        }
5177        if (pi.uriPermissionPatterns != null) {
5178            final int N = pi.uriPermissionPatterns.length;
5179            boolean allowed = false;
5180            for (int i=0; i<N; i++) {
5181                if (pi.uriPermissionPatterns[i] != null
5182                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5183                    allowed = true;
5184                    break;
5185                }
5186            }
5187            if (!allowed) {
5188                throw new SecurityException("Provider " + pi.packageName
5189                        + "/" + pi.name
5190                        + " does not allow granting of permission to path of Uri "
5191                        + uri);
5192            }
5193        }
5194
5195        // Third...  does the caller itself have permission to access
5196        // this uri?
5197        if (callingUid != Process.myUid()) {
5198            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5199                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5200                    throw new SecurityException("Uid " + callingUid
5201                            + " does not have permission to uri " + uri);
5202                }
5203            }
5204        }
5205
5206        return targetUid;
5207    }
5208
5209    public int checkGrantUriPermission(int callingUid, String targetPkg,
5210            Uri uri, int modeFlags) {
5211        enforceNotIsolatedCaller("checkGrantUriPermission");
5212        synchronized(this) {
5213            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5214        }
5215    }
5216
5217    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5218            Uri uri, int modeFlags, UriPermissionOwner owner) {
5219        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5220                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5221        if (modeFlags == 0) {
5222            return;
5223        }
5224
5225        // So here we are: the caller has the assumed permission
5226        // to the uri, and the target doesn't.  Let's now give this to
5227        // the target.
5228
5229        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5230                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5231
5232        HashMap<Uri, UriPermission> targetUris
5233                = mGrantedUriPermissions.get(targetUid);
5234        if (targetUris == null) {
5235            targetUris = new HashMap<Uri, UriPermission>();
5236            mGrantedUriPermissions.put(targetUid, targetUris);
5237        }
5238
5239        UriPermission perm = targetUris.get(uri);
5240        if (perm == null) {
5241            perm = new UriPermission(targetUid, uri);
5242            targetUris.put(uri, perm);
5243        }
5244
5245        perm.modeFlags |= modeFlags;
5246        if (owner == null) {
5247            perm.globalModeFlags |= modeFlags;
5248        } else {
5249            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5250                 perm.readOwners.add(owner);
5251                 owner.addReadPermission(perm);
5252            }
5253            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5254                 perm.writeOwners.add(owner);
5255                 owner.addWritePermission(perm);
5256            }
5257        }
5258    }
5259
5260    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5261            int modeFlags, UriPermissionOwner owner) {
5262        if (targetPkg == null) {
5263            throw new NullPointerException("targetPkg");
5264        }
5265
5266        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5267        if (targetUid < 0) {
5268            return;
5269        }
5270
5271        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5272    }
5273
5274    static class NeededUriGrants extends ArrayList<Uri> {
5275        final String targetPkg;
5276        final int targetUid;
5277        final int flags;
5278
5279        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5280            targetPkg = _targetPkg;
5281            targetUid = _targetUid;
5282            flags = _flags;
5283        }
5284    }
5285
5286    /**
5287     * Like checkGrantUriPermissionLocked, but takes an Intent.
5288     */
5289    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5290            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5291        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5292                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5293                + " clip=" + (intent != null ? intent.getClipData() : null)
5294                + " from " + intent + "; flags=0x"
5295                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5296
5297        if (targetPkg == null) {
5298            throw new NullPointerException("targetPkg");
5299        }
5300
5301        if (intent == null) {
5302            return null;
5303        }
5304        Uri data = intent.getData();
5305        ClipData clip = intent.getClipData();
5306        if (data == null && clip == null) {
5307            return null;
5308        }
5309        if (data != null) {
5310            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5311                mode, needed != null ? needed.targetUid : -1);
5312            if (target > 0) {
5313                if (needed == null) {
5314                    needed = new NeededUriGrants(targetPkg, target, mode);
5315                }
5316                needed.add(data);
5317            }
5318        }
5319        if (clip != null) {
5320            for (int i=0; i<clip.getItemCount(); i++) {
5321                Uri uri = clip.getItemAt(i).getUri();
5322                if (uri != null) {
5323                    int target = -1;
5324                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5325                            mode, needed != null ? needed.targetUid : -1);
5326                    if (target > 0) {
5327                        if (needed == null) {
5328                            needed = new NeededUriGrants(targetPkg, target, mode);
5329                        }
5330                        needed.add(uri);
5331                    }
5332                } else {
5333                    Intent clipIntent = clip.getItemAt(i).getIntent();
5334                    if (clipIntent != null) {
5335                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5336                                callingUid, targetPkg, clipIntent, mode, needed);
5337                        if (newNeeded != null) {
5338                            needed = newNeeded;
5339                        }
5340                    }
5341                }
5342            }
5343        }
5344
5345        return needed;
5346    }
5347
5348    /**
5349     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5350     */
5351    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5352            UriPermissionOwner owner) {
5353        if (needed != null) {
5354            for (int i=0; i<needed.size(); i++) {
5355                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5356                        needed.get(i), needed.flags, owner);
5357            }
5358        }
5359    }
5360
5361    void grantUriPermissionFromIntentLocked(int callingUid,
5362            String targetPkg, Intent intent, UriPermissionOwner owner) {
5363        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5364                intent, intent != null ? intent.getFlags() : 0, null);
5365        if (needed == null) {
5366            return;
5367        }
5368
5369        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5370    }
5371
5372    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5373            Uri uri, int modeFlags) {
5374        enforceNotIsolatedCaller("grantUriPermission");
5375        synchronized(this) {
5376            final ProcessRecord r = getRecordForAppLocked(caller);
5377            if (r == null) {
5378                throw new SecurityException("Unable to find app for caller "
5379                        + caller
5380                        + " when granting permission to uri " + uri);
5381            }
5382            if (targetPkg == null) {
5383                throw new IllegalArgumentException("null target");
5384            }
5385            if (uri == null) {
5386                throw new IllegalArgumentException("null uri");
5387            }
5388
5389            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5390                    null);
5391        }
5392    }
5393
5394    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5395        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5396                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5397            HashMap<Uri, UriPermission> perms
5398                    = mGrantedUriPermissions.get(perm.uid);
5399            if (perms != null) {
5400                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5401                        "Removing " + perm.uid + " permission to " + perm.uri);
5402                perms.remove(perm.uri);
5403                if (perms.size() == 0) {
5404                    mGrantedUriPermissions.remove(perm.uid);
5405                }
5406            }
5407        }
5408    }
5409
5410    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5411            int modeFlags) {
5412        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5413                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5414        if (modeFlags == 0) {
5415            return;
5416        }
5417
5418        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5419                "Revoking all granted permissions to " + uri);
5420
5421        final IPackageManager pm = AppGlobals.getPackageManager();
5422
5423        final String authority = uri.getAuthority();
5424        ProviderInfo pi = null;
5425        int userId = UserHandle.getUserId(callingUid);
5426        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5427        if (cpr != null) {
5428            pi = cpr.info;
5429        } else {
5430            try {
5431                pi = pm.resolveContentProvider(authority,
5432                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5433            } catch (RemoteException ex) {
5434            }
5435        }
5436        if (pi == null) {
5437            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5438            return;
5439        }
5440
5441        // Does the caller have this permission on the URI?
5442        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5443            // Right now, if you are not the original owner of the permission,
5444            // you are not allowed to revoke it.
5445            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5446                throw new SecurityException("Uid " + callingUid
5447                        + " does not have permission to uri " + uri);
5448            //}
5449        }
5450
5451        // Go through all of the permissions and remove any that match.
5452        final List<String> SEGMENTS = uri.getPathSegments();
5453        if (SEGMENTS != null) {
5454            final int NS = SEGMENTS.size();
5455            int N = mGrantedUriPermissions.size();
5456            for (int i=0; i<N; i++) {
5457                HashMap<Uri, UriPermission> perms
5458                        = mGrantedUriPermissions.valueAt(i);
5459                Iterator<UriPermission> it = perms.values().iterator();
5460            toploop:
5461                while (it.hasNext()) {
5462                    UriPermission perm = it.next();
5463                    Uri targetUri = perm.uri;
5464                    if (!authority.equals(targetUri.getAuthority())) {
5465                        continue;
5466                    }
5467                    List<String> targetSegments = targetUri.getPathSegments();
5468                    if (targetSegments == null) {
5469                        continue;
5470                    }
5471                    if (targetSegments.size() < NS) {
5472                        continue;
5473                    }
5474                    for (int j=0; j<NS; j++) {
5475                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5476                            continue toploop;
5477                        }
5478                    }
5479                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5480                            "Revoking " + perm.uid + " permission to " + perm.uri);
5481                    perm.clearModes(modeFlags);
5482                    if (perm.modeFlags == 0) {
5483                        it.remove();
5484                    }
5485                }
5486                if (perms.size() == 0) {
5487                    mGrantedUriPermissions.remove(
5488                            mGrantedUriPermissions.keyAt(i));
5489                    N--;
5490                    i--;
5491                }
5492            }
5493        }
5494    }
5495
5496    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5497            int modeFlags) {
5498        enforceNotIsolatedCaller("revokeUriPermission");
5499        synchronized(this) {
5500            final ProcessRecord r = getRecordForAppLocked(caller);
5501            if (r == null) {
5502                throw new SecurityException("Unable to find app for caller "
5503                        + caller
5504                        + " when revoking permission to uri " + uri);
5505            }
5506            if (uri == null) {
5507                Slog.w(TAG, "revokeUriPermission: null uri");
5508                return;
5509            }
5510
5511            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5512                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5513            if (modeFlags == 0) {
5514                return;
5515            }
5516
5517            final IPackageManager pm = AppGlobals.getPackageManager();
5518
5519            final String authority = uri.getAuthority();
5520            ProviderInfo pi = null;
5521            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5522            if (cpr != null) {
5523                pi = cpr.info;
5524            } else {
5525                try {
5526                    pi = pm.resolveContentProvider(authority,
5527                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5528                } catch (RemoteException ex) {
5529                }
5530            }
5531            if (pi == null) {
5532                Slog.w(TAG, "No content provider found for permission revoke: "
5533                        + uri.toSafeString());
5534                return;
5535            }
5536
5537            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5538        }
5539    }
5540
5541    @Override
5542    public IBinder newUriPermissionOwner(String name) {
5543        enforceNotIsolatedCaller("newUriPermissionOwner");
5544        synchronized(this) {
5545            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5546            return owner.getExternalTokenLocked();
5547        }
5548    }
5549
5550    @Override
5551    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5552            Uri uri, int modeFlags) {
5553        synchronized(this) {
5554            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5555            if (owner == null) {
5556                throw new IllegalArgumentException("Unknown owner: " + token);
5557            }
5558            if (fromUid != Binder.getCallingUid()) {
5559                if (Binder.getCallingUid() != Process.myUid()) {
5560                    // Only system code can grant URI permissions on behalf
5561                    // of other users.
5562                    throw new SecurityException("nice try");
5563                }
5564            }
5565            if (targetPkg == null) {
5566                throw new IllegalArgumentException("null target");
5567            }
5568            if (uri == null) {
5569                throw new IllegalArgumentException("null uri");
5570            }
5571
5572            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5573        }
5574    }
5575
5576    @Override
5577    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5578        synchronized(this) {
5579            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5580            if (owner == null) {
5581                throw new IllegalArgumentException("Unknown owner: " + token);
5582            }
5583
5584            if (uri == null) {
5585                owner.removeUriPermissionsLocked(mode);
5586            } else {
5587                owner.removeUriPermissionLocked(uri, mode);
5588            }
5589        }
5590    }
5591
5592    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5593        synchronized (this) {
5594            ProcessRecord app =
5595                who != null ? getRecordForAppLocked(who) : null;
5596            if (app == null) return;
5597
5598            Message msg = Message.obtain();
5599            msg.what = WAIT_FOR_DEBUGGER_MSG;
5600            msg.obj = app;
5601            msg.arg1 = waiting ? 1 : 0;
5602            mHandler.sendMessage(msg);
5603        }
5604    }
5605
5606    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5607        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5608        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5609        outInfo.availMem = Process.getFreeMemory();
5610        outInfo.totalMem = Process.getTotalMemory();
5611        outInfo.threshold = homeAppMem;
5612        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5613        outInfo.hiddenAppThreshold = hiddenAppMem;
5614        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5615                ProcessList.SERVICE_ADJ);
5616        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5617                ProcessList.VISIBLE_APP_ADJ);
5618        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5619                ProcessList.FOREGROUND_APP_ADJ);
5620    }
5621
5622    // =========================================================
5623    // TASK MANAGEMENT
5624    // =========================================================
5625
5626    public List getTasks(int maxNum, int flags,
5627                         IThumbnailReceiver receiver) {
5628        ArrayList list = new ArrayList();
5629
5630        PendingThumbnailsRecord pending = null;
5631        IApplicationThread topThumbnail = null;
5632        ActivityRecord topRecord = null;
5633
5634        synchronized(this) {
5635            if (localLOGV) Slog.v(
5636                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5637                + ", receiver=" + receiver);
5638
5639            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5640                    != PackageManager.PERMISSION_GRANTED) {
5641                if (receiver != null) {
5642                    // If the caller wants to wait for pending thumbnails,
5643                    // it ain't gonna get them.
5644                    try {
5645                        receiver.finished();
5646                    } catch (RemoteException ex) {
5647                    }
5648                }
5649                String msg = "Permission Denial: getTasks() from pid="
5650                        + Binder.getCallingPid()
5651                        + ", uid=" + Binder.getCallingUid()
5652                        + " requires " + android.Manifest.permission.GET_TASKS;
5653                Slog.w(TAG, msg);
5654                throw new SecurityException(msg);
5655            }
5656
5657            int pos = mMainStack.mHistory.size()-1;
5658            ActivityRecord next =
5659                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5660            ActivityRecord top = null;
5661            TaskRecord curTask = null;
5662            int numActivities = 0;
5663            int numRunning = 0;
5664            while (pos >= 0 && maxNum > 0) {
5665                final ActivityRecord r = next;
5666                pos--;
5667                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5668
5669                // Initialize state for next task if needed.
5670                if (top == null ||
5671                        (top.state == ActivityState.INITIALIZING
5672                            && top.task == r.task)) {
5673                    top = r;
5674                    curTask = r.task;
5675                    numActivities = numRunning = 0;
5676                }
5677
5678                // Add 'r' into the current task.
5679                numActivities++;
5680                if (r.app != null && r.app.thread != null) {
5681                    numRunning++;
5682                }
5683
5684                if (localLOGV) Slog.v(
5685                    TAG, r.intent.getComponent().flattenToShortString()
5686                    + ": task=" + r.task);
5687
5688                // If the next one is a different task, generate a new
5689                // TaskInfo entry for what we have.
5690                if (next == null || next.task != curTask) {
5691                    ActivityManager.RunningTaskInfo ci
5692                            = new ActivityManager.RunningTaskInfo();
5693                    ci.id = curTask.taskId;
5694                    ci.baseActivity = r.intent.getComponent();
5695                    ci.topActivity = top.intent.getComponent();
5696                    if (top.thumbHolder != null) {
5697                        ci.description = top.thumbHolder.lastDescription;
5698                    }
5699                    ci.numActivities = numActivities;
5700                    ci.numRunning = numRunning;
5701                    //System.out.println(
5702                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5703                    if (ci.thumbnail == null && receiver != null) {
5704                        if (localLOGV) Slog.v(
5705                            TAG, "State=" + top.state + "Idle=" + top.idle
5706                            + " app=" + top.app
5707                            + " thr=" + (top.app != null ? top.app.thread : null));
5708                        if (top.state == ActivityState.RESUMED
5709                                || top.state == ActivityState.PAUSING) {
5710                            if (top.idle && top.app != null
5711                                && top.app.thread != null) {
5712                                topRecord = top;
5713                                topThumbnail = top.app.thread;
5714                            } else {
5715                                top.thumbnailNeeded = true;
5716                            }
5717                        }
5718                        if (pending == null) {
5719                            pending = new PendingThumbnailsRecord(receiver);
5720                        }
5721                        pending.pendingRecords.add(top);
5722                    }
5723                    list.add(ci);
5724                    maxNum--;
5725                    top = null;
5726                }
5727            }
5728
5729            if (pending != null) {
5730                mPendingThumbnails.add(pending);
5731            }
5732        }
5733
5734        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5735
5736        if (topThumbnail != null) {
5737            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5738            try {
5739                topThumbnail.requestThumbnail(topRecord.appToken);
5740            } catch (Exception e) {
5741                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5742                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5743            }
5744        }
5745
5746        if (pending == null && receiver != null) {
5747            // In this case all thumbnails were available and the client
5748            // is being asked to be told when the remaining ones come in...
5749            // which is unusually, since the top-most currently running
5750            // activity should never have a canned thumbnail!  Oh well.
5751            try {
5752                receiver.finished();
5753            } catch (RemoteException ex) {
5754            }
5755        }
5756
5757        return list;
5758    }
5759
5760    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5761            int flags, int userId) {
5762        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5763                false, true, "getRecentTasks", null);
5764
5765        synchronized (this) {
5766            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5767                    "getRecentTasks()");
5768            final boolean detailed = checkCallingPermission(
5769                    android.Manifest.permission.GET_DETAILED_TASKS)
5770                    == PackageManager.PERMISSION_GRANTED;
5771
5772            IPackageManager pm = AppGlobals.getPackageManager();
5773
5774            final int N = mRecentTasks.size();
5775            ArrayList<ActivityManager.RecentTaskInfo> res
5776                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5777                            maxNum < N ? maxNum : N);
5778            for (int i=0; i<N && maxNum > 0; i++) {
5779                TaskRecord tr = mRecentTasks.get(i);
5780                // Only add calling user's recent tasks
5781                if (tr.userId != userId) continue;
5782                // Return the entry if desired by the caller.  We always return
5783                // the first entry, because callers always expect this to be the
5784                // foreground app.  We may filter others if the caller has
5785                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5786                // we should exclude the entry.
5787
5788                if (i == 0
5789                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5790                        || (tr.intent == null)
5791                        || ((tr.intent.getFlags()
5792                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5793                    ActivityManager.RecentTaskInfo rti
5794                            = new ActivityManager.RecentTaskInfo();
5795                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5796                    rti.persistentId = tr.taskId;
5797                    rti.baseIntent = new Intent(
5798                            tr.intent != null ? tr.intent : tr.affinityIntent);
5799                    if (!detailed) {
5800                        rti.baseIntent.replaceExtras((Bundle)null);
5801                    }
5802                    rti.origActivity = tr.origActivity;
5803                    rti.description = tr.lastDescription;
5804
5805                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5806                        // Check whether this activity is currently available.
5807                        try {
5808                            if (rti.origActivity != null) {
5809                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5810                                        == null) {
5811                                    continue;
5812                                }
5813                            } else if (rti.baseIntent != null) {
5814                                if (pm.queryIntentActivities(rti.baseIntent,
5815                                        null, 0, userId) == null) {
5816                                    continue;
5817                                }
5818                            }
5819                        } catch (RemoteException e) {
5820                            // Will never happen.
5821                        }
5822                    }
5823
5824                    res.add(rti);
5825                    maxNum--;
5826                }
5827            }
5828            return res;
5829        }
5830    }
5831
5832    private TaskRecord taskForIdLocked(int id) {
5833        final int N = mRecentTasks.size();
5834        for (int i=0; i<N; i++) {
5835            TaskRecord tr = mRecentTasks.get(i);
5836            if (tr.taskId == id) {
5837                return tr;
5838            }
5839        }
5840        return null;
5841    }
5842
5843    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5844        synchronized (this) {
5845            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5846                    "getTaskThumbnails()");
5847            TaskRecord tr = taskForIdLocked(id);
5848            if (tr != null) {
5849                return mMainStack.getTaskThumbnailsLocked(tr);
5850            }
5851        }
5852        return null;
5853    }
5854
5855    public Bitmap getTaskTopThumbnail(int id) {
5856        synchronized (this) {
5857            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5858                    "getTaskTopThumbnail()");
5859            TaskRecord tr = taskForIdLocked(id);
5860            if (tr != null) {
5861                return mMainStack.getTaskTopThumbnailLocked(tr);
5862            }
5863        }
5864        return null;
5865    }
5866
5867    public boolean removeSubTask(int taskId, int subTaskIndex) {
5868        synchronized (this) {
5869            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5870                    "removeSubTask()");
5871            long ident = Binder.clearCallingIdentity();
5872            try {
5873                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5874                        true) != null;
5875            } finally {
5876                Binder.restoreCallingIdentity(ident);
5877            }
5878        }
5879    }
5880
5881    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5882        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5883        Intent baseIntent = new Intent(
5884                tr.intent != null ? tr.intent : tr.affinityIntent);
5885        ComponentName component = baseIntent.getComponent();
5886        if (component == null) {
5887            Slog.w(TAG, "Now component for base intent of task: " + tr);
5888            return;
5889        }
5890
5891        // Find any running services associated with this app.
5892        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5893
5894        if (killProcesses) {
5895            // Find any running processes associated with this app.
5896            final String pkg = component.getPackageName();
5897            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5898            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5899            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5900                for (int i=0; i<uids.size(); i++) {
5901                    ProcessRecord proc = uids.valueAt(i);
5902                    if (proc.userId != tr.userId) {
5903                        continue;
5904                    }
5905                    if (!proc.pkgList.contains(pkg)) {
5906                        continue;
5907                    }
5908                    procs.add(proc);
5909                }
5910            }
5911
5912            // Kill the running processes.
5913            for (int i=0; i<procs.size(); i++) {
5914                ProcessRecord pr = procs.get(i);
5915                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5916                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5917                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5918                            pr.processName, pr.setAdj, "remove task");
5919                    pr.killedBackground = true;
5920                    Process.killProcessQuiet(pr.pid);
5921                } else {
5922                    pr.waitingToKill = "remove task";
5923                }
5924            }
5925        }
5926    }
5927
5928    public boolean removeTask(int taskId, int flags) {
5929        synchronized (this) {
5930            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5931                    "removeTask()");
5932            long ident = Binder.clearCallingIdentity();
5933            try {
5934                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5935                        false);
5936                if (r != null) {
5937                    mRecentTasks.remove(r.task);
5938                    cleanUpRemovedTaskLocked(r.task, flags);
5939                    return true;
5940                } else {
5941                    TaskRecord tr = null;
5942                    int i=0;
5943                    while (i < mRecentTasks.size()) {
5944                        TaskRecord t = mRecentTasks.get(i);
5945                        if (t.taskId == taskId) {
5946                            tr = t;
5947                            break;
5948                        }
5949                        i++;
5950                    }
5951                    if (tr != null) {
5952                        if (tr.numActivities <= 0) {
5953                            // Caller is just removing a recent task that is
5954                            // not actively running.  That is easy!
5955                            mRecentTasks.remove(i);
5956                            cleanUpRemovedTaskLocked(tr, flags);
5957                            return true;
5958                        } else {
5959                            Slog.w(TAG, "removeTask: task " + taskId
5960                                    + " does not have activities to remove, "
5961                                    + " but numActivities=" + tr.numActivities
5962                                    + ": " + tr);
5963                        }
5964                    }
5965                }
5966            } finally {
5967                Binder.restoreCallingIdentity(ident);
5968            }
5969        }
5970        return false;
5971    }
5972
5973    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5974        int j;
5975        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5976        TaskRecord jt = startTask;
5977
5978        // First look backwards
5979        for (j=startIndex-1; j>=0; j--) {
5980            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5981            if (r.task != jt) {
5982                jt = r.task;
5983                if (affinity.equals(jt.affinity)) {
5984                    return j;
5985                }
5986            }
5987        }
5988
5989        // Now look forwards
5990        final int N = mMainStack.mHistory.size();
5991        jt = startTask;
5992        for (j=startIndex+1; j<N; j++) {
5993            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5994            if (r.task != jt) {
5995                if (affinity.equals(jt.affinity)) {
5996                    return j;
5997                }
5998                jt = r.task;
5999            }
6000        }
6001
6002        // Might it be at the top?
6003        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6004            return N-1;
6005        }
6006
6007        return -1;
6008    }
6009
6010    /**
6011     * TODO: Add mController hook
6012     */
6013    public void moveTaskToFront(int task, int flags, Bundle options) {
6014        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6015                "moveTaskToFront()");
6016
6017        synchronized(this) {
6018            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6019                    Binder.getCallingUid(), "Task to front")) {
6020                ActivityOptions.abort(options);
6021                return;
6022            }
6023            final long origId = Binder.clearCallingIdentity();
6024            try {
6025                TaskRecord tr = taskForIdLocked(task);
6026                if (tr != null) {
6027                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6028                        mMainStack.mUserLeaving = true;
6029                    }
6030                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6031                        // Caller wants the home activity moved with it.  To accomplish this,
6032                        // we'll just move the home task to the top first.
6033                        mMainStack.moveHomeToFrontLocked();
6034                    }
6035                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6036                    return;
6037                }
6038                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6039                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6040                    if (hr.task.taskId == task) {
6041                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6042                            mMainStack.mUserLeaving = true;
6043                        }
6044                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6045                            // Caller wants the home activity moved with it.  To accomplish this,
6046                            // we'll just move the home task to the top first.
6047                            mMainStack.moveHomeToFrontLocked();
6048                        }
6049                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6050                        return;
6051                    }
6052                }
6053            } finally {
6054                Binder.restoreCallingIdentity(origId);
6055            }
6056            ActivityOptions.abort(options);
6057        }
6058    }
6059
6060    public void moveTaskToBack(int task) {
6061        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6062                "moveTaskToBack()");
6063
6064        synchronized(this) {
6065            if (mMainStack.mResumedActivity != null
6066                    && mMainStack.mResumedActivity.task.taskId == task) {
6067                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6068                        Binder.getCallingUid(), "Task to back")) {
6069                    return;
6070                }
6071            }
6072            final long origId = Binder.clearCallingIdentity();
6073            mMainStack.moveTaskToBackLocked(task, null);
6074            Binder.restoreCallingIdentity(origId);
6075        }
6076    }
6077
6078    /**
6079     * Moves an activity, and all of the other activities within the same task, to the bottom
6080     * of the history stack.  The activity's order within the task is unchanged.
6081     *
6082     * @param token A reference to the activity we wish to move
6083     * @param nonRoot If false then this only works if the activity is the root
6084     *                of a task; if true it will work for any activity in a task.
6085     * @return Returns true if the move completed, false if not.
6086     */
6087    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6088        enforceNotIsolatedCaller("moveActivityTaskToBack");
6089        synchronized(this) {
6090            final long origId = Binder.clearCallingIdentity();
6091            int taskId = getTaskForActivityLocked(token, !nonRoot);
6092            if (taskId >= 0) {
6093                return mMainStack.moveTaskToBackLocked(taskId, null);
6094            }
6095            Binder.restoreCallingIdentity(origId);
6096        }
6097        return false;
6098    }
6099
6100    public void moveTaskBackwards(int task) {
6101        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6102                "moveTaskBackwards()");
6103
6104        synchronized(this) {
6105            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6106                    Binder.getCallingUid(), "Task backwards")) {
6107                return;
6108            }
6109            final long origId = Binder.clearCallingIdentity();
6110            moveTaskBackwardsLocked(task);
6111            Binder.restoreCallingIdentity(origId);
6112        }
6113    }
6114
6115    private final void moveTaskBackwardsLocked(int task) {
6116        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6117    }
6118
6119    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6120        synchronized(this) {
6121            return getTaskForActivityLocked(token, onlyRoot);
6122        }
6123    }
6124
6125    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6126        final int N = mMainStack.mHistory.size();
6127        TaskRecord lastTask = null;
6128        for (int i=0; i<N; i++) {
6129            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6130            if (r.appToken == token) {
6131                if (!onlyRoot || lastTask != r.task) {
6132                    return r.task.taskId;
6133                }
6134                return -1;
6135            }
6136            lastTask = r.task;
6137        }
6138
6139        return -1;
6140    }
6141
6142    // =========================================================
6143    // THUMBNAILS
6144    // =========================================================
6145
6146    public void reportThumbnail(IBinder token,
6147            Bitmap thumbnail, CharSequence description) {
6148        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6149        final long origId = Binder.clearCallingIdentity();
6150        sendPendingThumbnail(null, token, thumbnail, description, true);
6151        Binder.restoreCallingIdentity(origId);
6152    }
6153
6154    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6155            Bitmap thumbnail, CharSequence description, boolean always) {
6156        TaskRecord task = null;
6157        ArrayList receivers = null;
6158
6159        //System.out.println("Send pending thumbnail: " + r);
6160
6161        synchronized(this) {
6162            if (r == null) {
6163                r = mMainStack.isInStackLocked(token);
6164                if (r == null) {
6165                    return;
6166                }
6167            }
6168            if (thumbnail == null && r.thumbHolder != null) {
6169                thumbnail = r.thumbHolder.lastThumbnail;
6170                description = r.thumbHolder.lastDescription;
6171            }
6172            if (thumbnail == null && !always) {
6173                // If there is no thumbnail, and this entry is not actually
6174                // going away, then abort for now and pick up the next
6175                // thumbnail we get.
6176                return;
6177            }
6178            task = r.task;
6179
6180            int N = mPendingThumbnails.size();
6181            int i=0;
6182            while (i<N) {
6183                PendingThumbnailsRecord pr =
6184                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6185                //System.out.println("Looking in " + pr.pendingRecords);
6186                if (pr.pendingRecords.remove(r)) {
6187                    if (receivers == null) {
6188                        receivers = new ArrayList();
6189                    }
6190                    receivers.add(pr);
6191                    if (pr.pendingRecords.size() == 0) {
6192                        pr.finished = true;
6193                        mPendingThumbnails.remove(i);
6194                        N--;
6195                        continue;
6196                    }
6197                }
6198                i++;
6199            }
6200        }
6201
6202        if (receivers != null) {
6203            final int N = receivers.size();
6204            for (int i=0; i<N; i++) {
6205                try {
6206                    PendingThumbnailsRecord pr =
6207                        (PendingThumbnailsRecord)receivers.get(i);
6208                    pr.receiver.newThumbnail(
6209                        task != null ? task.taskId : -1, thumbnail, description);
6210                    if (pr.finished) {
6211                        pr.receiver.finished();
6212                    }
6213                } catch (Exception e) {
6214                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6215                }
6216            }
6217        }
6218    }
6219
6220    // =========================================================
6221    // CONTENT PROVIDERS
6222    // =========================================================
6223
6224    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6225        List<ProviderInfo> providers = null;
6226        try {
6227            providers = AppGlobals.getPackageManager().
6228                queryContentProviders(app.processName, app.uid,
6229                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6230        } catch (RemoteException ex) {
6231        }
6232        if (DEBUG_MU)
6233            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6234        int userId = app.userId;
6235        if (providers != null) {
6236            int N = providers.size();
6237            for (int i=0; i<N; i++) {
6238                ProviderInfo cpi =
6239                    (ProviderInfo)providers.get(i);
6240                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6241                        cpi.name, cpi.flags);
6242                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6243                    // This is a singleton provider, but a user besides the
6244                    // default user is asking to initialize a process it runs
6245                    // in...  well, no, it doesn't actually run in this process,
6246                    // it runs in the process of the default user.  Get rid of it.
6247                    providers.remove(i);
6248                    N--;
6249                    continue;
6250                }
6251
6252                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6253                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6254                if (cpr == null) {
6255                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6256                    mProviderMap.putProviderByClass(comp, cpr);
6257                }
6258                if (DEBUG_MU)
6259                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6260                app.pubProviders.put(cpi.name, cpr);
6261                app.addPackage(cpi.applicationInfo.packageName);
6262                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6263            }
6264        }
6265        return providers;
6266    }
6267
6268    /**
6269     * Check if {@link ProcessRecord} has a possible chance at accessing the
6270     * given {@link ProviderInfo}. Final permission checking is always done
6271     * in {@link ContentProvider}.
6272     */
6273    private final String checkContentProviderPermissionLocked(
6274            ProviderInfo cpi, ProcessRecord r) {
6275        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6276        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6277        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6278                cpi.applicationInfo.uid, cpi.exported)
6279                == PackageManager.PERMISSION_GRANTED) {
6280            return null;
6281        }
6282        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6283                cpi.applicationInfo.uid, cpi.exported)
6284                == PackageManager.PERMISSION_GRANTED) {
6285            return null;
6286        }
6287
6288        PathPermission[] pps = cpi.pathPermissions;
6289        if (pps != null) {
6290            int i = pps.length;
6291            while (i > 0) {
6292                i--;
6293                PathPermission pp = pps[i];
6294                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6295                        cpi.applicationInfo.uid, cpi.exported)
6296                        == PackageManager.PERMISSION_GRANTED) {
6297                    return null;
6298                }
6299                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6300                        cpi.applicationInfo.uid, cpi.exported)
6301                        == PackageManager.PERMISSION_GRANTED) {
6302                    return null;
6303                }
6304            }
6305        }
6306
6307        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6308        if (perms != null) {
6309            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6310                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6311                    return null;
6312                }
6313            }
6314        }
6315
6316        String msg;
6317        if (!cpi.exported) {
6318            msg = "Permission Denial: opening provider " + cpi.name
6319                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6320                    + ", uid=" + callingUid + ") that is not exported from uid "
6321                    + cpi.applicationInfo.uid;
6322        } else {
6323            msg = "Permission Denial: opening provider " + cpi.name
6324                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6325                    + ", uid=" + callingUid + ") requires "
6326                    + cpi.readPermission + " or " + cpi.writePermission;
6327        }
6328        Slog.w(TAG, msg);
6329        return msg;
6330    }
6331
6332    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6333            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6334        if (r != null) {
6335            for (int i=0; i<r.conProviders.size(); i++) {
6336                ContentProviderConnection conn = r.conProviders.get(i);
6337                if (conn.provider == cpr) {
6338                    if (DEBUG_PROVIDER) Slog.v(TAG,
6339                            "Adding provider requested by "
6340                            + r.processName + " from process "
6341                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6342                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6343                    if (stable) {
6344                        conn.stableCount++;
6345                        conn.numStableIncs++;
6346                    } else {
6347                        conn.unstableCount++;
6348                        conn.numUnstableIncs++;
6349                    }
6350                    return conn;
6351                }
6352            }
6353            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6354            if (stable) {
6355                conn.stableCount = 1;
6356                conn.numStableIncs = 1;
6357            } else {
6358                conn.unstableCount = 1;
6359                conn.numUnstableIncs = 1;
6360            }
6361            cpr.connections.add(conn);
6362            r.conProviders.add(conn);
6363            return conn;
6364        }
6365        cpr.addExternalProcessHandleLocked(externalProcessToken);
6366        return null;
6367    }
6368
6369    boolean decProviderCountLocked(ContentProviderConnection conn,
6370            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6371        if (conn != null) {
6372            cpr = conn.provider;
6373            if (DEBUG_PROVIDER) Slog.v(TAG,
6374                    "Removing provider requested by "
6375                    + conn.client.processName + " from process "
6376                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6377                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6378            if (stable) {
6379                conn.stableCount--;
6380            } else {
6381                conn.unstableCount--;
6382            }
6383            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6384                cpr.connections.remove(conn);
6385                conn.client.conProviders.remove(conn);
6386                return true;
6387            }
6388            return false;
6389        }
6390        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6391        return false;
6392    }
6393
6394    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6395            String name, IBinder token, boolean stable, int userId) {
6396        ContentProviderRecord cpr;
6397        ContentProviderConnection conn = null;
6398        ProviderInfo cpi = null;
6399
6400        synchronized(this) {
6401            ProcessRecord r = null;
6402            if (caller != null) {
6403                r = getRecordForAppLocked(caller);
6404                if (r == null) {
6405                    throw new SecurityException(
6406                            "Unable to find app for caller " + caller
6407                          + " (pid=" + Binder.getCallingPid()
6408                          + ") when getting content provider " + name);
6409                }
6410            }
6411
6412            // First check if this content provider has been published...
6413            cpr = mProviderMap.getProviderByName(name, userId);
6414            boolean providerRunning = cpr != null;
6415            if (providerRunning) {
6416                cpi = cpr.info;
6417                String msg;
6418                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6419                    throw new SecurityException(msg);
6420                }
6421
6422                if (r != null && cpr.canRunHere(r)) {
6423                    // This provider has been published or is in the process
6424                    // of being published...  but it is also allowed to run
6425                    // in the caller's process, so don't make a connection
6426                    // and just let the caller instantiate its own instance.
6427                    ContentProviderHolder holder = cpr.newHolder(null);
6428                    // don't give caller the provider object, it needs
6429                    // to make its own.
6430                    holder.provider = null;
6431                    return holder;
6432                }
6433
6434                final long origId = Binder.clearCallingIdentity();
6435
6436                // In this case the provider instance already exists, so we can
6437                // return it right away.
6438                conn = incProviderCountLocked(r, cpr, token, stable);
6439                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6440                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6441                        // If this is a perceptible app accessing the provider,
6442                        // make sure to count it as being accessed and thus
6443                        // back up on the LRU list.  This is good because
6444                        // content providers are often expensive to start.
6445                        updateLruProcessLocked(cpr.proc, false, true);
6446                    }
6447                }
6448
6449                if (cpr.proc != null) {
6450                    if (false) {
6451                        if (cpr.name.flattenToShortString().equals(
6452                                "com.android.providers.calendar/.CalendarProvider2")) {
6453                            Slog.v(TAG, "****************** KILLING "
6454                                + cpr.name.flattenToShortString());
6455                            Process.killProcess(cpr.proc.pid);
6456                        }
6457                    }
6458                    boolean success = updateOomAdjLocked(cpr.proc);
6459                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6460                    // NOTE: there is still a race here where a signal could be
6461                    // pending on the process even though we managed to update its
6462                    // adj level.  Not sure what to do about this, but at least
6463                    // the race is now smaller.
6464                    if (!success) {
6465                        // Uh oh...  it looks like the provider's process
6466                        // has been killed on us.  We need to wait for a new
6467                        // process to be started, and make sure its death
6468                        // doesn't kill our process.
6469                        Slog.i(TAG,
6470                                "Existing provider " + cpr.name.flattenToShortString()
6471                                + " is crashing; detaching " + r);
6472                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6473                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6474                        if (!lastRef) {
6475                            // This wasn't the last ref our process had on
6476                            // the provider...  we have now been killed, bail.
6477                            return null;
6478                        }
6479                        providerRunning = false;
6480                        conn = null;
6481                    }
6482                }
6483
6484                Binder.restoreCallingIdentity(origId);
6485            }
6486
6487            boolean singleton;
6488            if (!providerRunning) {
6489                try {
6490                    cpi = AppGlobals.getPackageManager().
6491                        resolveContentProvider(name,
6492                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6493                } catch (RemoteException ex) {
6494                }
6495                if (cpi == null) {
6496                    return null;
6497                }
6498                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6499                        cpi.name, cpi.flags);
6500                if (singleton) {
6501                    userId = 0;
6502                }
6503                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6504
6505                String msg;
6506                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6507                    throw new SecurityException(msg);
6508                }
6509
6510                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6511                        && !cpi.processName.equals("system")) {
6512                    // If this content provider does not run in the system
6513                    // process, and the system is not yet ready to run other
6514                    // processes, then fail fast instead of hanging.
6515                    throw new IllegalArgumentException(
6516                            "Attempt to launch content provider before system ready");
6517                }
6518
6519                // Make sure that the user who owns this provider is started.  If not,
6520                // we don't want to allow it to run.
6521                if (mStartedUsers.get(userId) == null) {
6522                    Slog.w(TAG, "Unable to launch app "
6523                            + cpi.applicationInfo.packageName + "/"
6524                            + cpi.applicationInfo.uid + " for provider "
6525                            + name + ": user " + userId + " is stopped");
6526                    return null;
6527                }
6528
6529                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6530                cpr = mProviderMap.getProviderByClass(comp, userId);
6531                final boolean firstClass = cpr == null;
6532                if (firstClass) {
6533                    try {
6534                        ApplicationInfo ai =
6535                            AppGlobals.getPackageManager().
6536                                getApplicationInfo(
6537                                        cpi.applicationInfo.packageName,
6538                                        STOCK_PM_FLAGS, userId);
6539                        if (ai == null) {
6540                            Slog.w(TAG, "No package info for content provider "
6541                                    + cpi.name);
6542                            return null;
6543                        }
6544                        ai = getAppInfoForUser(ai, userId);
6545                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6546                    } catch (RemoteException ex) {
6547                        // pm is in same process, this will never happen.
6548                    }
6549                }
6550
6551                if (r != null && cpr.canRunHere(r)) {
6552                    // If this is a multiprocess provider, then just return its
6553                    // info and allow the caller to instantiate it.  Only do
6554                    // this if the provider is the same user as the caller's
6555                    // process, or can run as root (so can be in any process).
6556                    return cpr.newHolder(null);
6557                }
6558
6559                if (DEBUG_PROVIDER) {
6560                    RuntimeException e = new RuntimeException("here");
6561                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6562                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6563                }
6564
6565                // This is single process, and our app is now connecting to it.
6566                // See if we are already in the process of launching this
6567                // provider.
6568                final int N = mLaunchingProviders.size();
6569                int i;
6570                for (i=0; i<N; i++) {
6571                    if (mLaunchingProviders.get(i) == cpr) {
6572                        break;
6573                    }
6574                }
6575
6576                // If the provider is not already being launched, then get it
6577                // started.
6578                if (i >= N) {
6579                    final long origId = Binder.clearCallingIdentity();
6580
6581                    try {
6582                        // Content provider is now in use, its package can't be stopped.
6583                        try {
6584                            AppGlobals.getPackageManager().setPackageStoppedState(
6585                                    cpr.appInfo.packageName, false, userId);
6586                        } catch (RemoteException e) {
6587                        } catch (IllegalArgumentException e) {
6588                            Slog.w(TAG, "Failed trying to unstop package "
6589                                    + cpr.appInfo.packageName + ": " + e);
6590                        }
6591
6592                        ProcessRecord proc = startProcessLocked(cpi.processName,
6593                                cpr.appInfo, false, 0, "content provider",
6594                                new ComponentName(cpi.applicationInfo.packageName,
6595                                        cpi.name), false, false);
6596                        if (proc == null) {
6597                            Slog.w(TAG, "Unable to launch app "
6598                                    + cpi.applicationInfo.packageName + "/"
6599                                    + cpi.applicationInfo.uid + " for provider "
6600                                    + name + ": process is bad");
6601                            return null;
6602                        }
6603                        cpr.launchingApp = proc;
6604                        mLaunchingProviders.add(cpr);
6605                    } finally {
6606                        Binder.restoreCallingIdentity(origId);
6607                    }
6608                }
6609
6610                // Make sure the provider is published (the same provider class
6611                // may be published under multiple names).
6612                if (firstClass) {
6613                    mProviderMap.putProviderByClass(comp, cpr);
6614                }
6615
6616                mProviderMap.putProviderByName(name, cpr);
6617                conn = incProviderCountLocked(r, cpr, token, stable);
6618                if (conn != null) {
6619                    conn.waiting = true;
6620                }
6621            }
6622        }
6623
6624        // Wait for the provider to be published...
6625        synchronized (cpr) {
6626            while (cpr.provider == null) {
6627                if (cpr.launchingApp == null) {
6628                    Slog.w(TAG, "Unable to launch app "
6629                            + cpi.applicationInfo.packageName + "/"
6630                            + cpi.applicationInfo.uid + " for provider "
6631                            + name + ": launching app became null");
6632                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6633                            cpi.applicationInfo.packageName,
6634                            cpi.applicationInfo.uid, name);
6635                    return null;
6636                }
6637                try {
6638                    if (DEBUG_MU) {
6639                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6640                                + cpr.launchingApp);
6641                    }
6642                    if (conn != null) {
6643                        conn.waiting = true;
6644                    }
6645                    cpr.wait();
6646                } catch (InterruptedException ex) {
6647                } finally {
6648                    if (conn != null) {
6649                        conn.waiting = false;
6650                    }
6651                }
6652            }
6653        }
6654        return cpr != null ? cpr.newHolder(conn) : null;
6655    }
6656
6657    public final ContentProviderHolder getContentProvider(
6658            IApplicationThread caller, String name, int userId, boolean stable) {
6659        enforceNotIsolatedCaller("getContentProvider");
6660        if (caller == null) {
6661            String msg = "null IApplicationThread when getting content provider "
6662                    + name;
6663            Slog.w(TAG, msg);
6664            throw new SecurityException(msg);
6665        }
6666
6667        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6668                false, true, "getContentProvider", null);
6669        return getContentProviderImpl(caller, name, null, stable, userId);
6670    }
6671
6672    public ContentProviderHolder getContentProviderExternal(
6673            String name, int userId, IBinder token) {
6674        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6675            "Do not have permission in call getContentProviderExternal()");
6676        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6677                false, true, "getContentProvider", null);
6678        return getContentProviderExternalUnchecked(name, token, userId);
6679    }
6680
6681    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6682            IBinder token, int userId) {
6683        return getContentProviderImpl(null, name, token, true, userId);
6684    }
6685
6686    /**
6687     * Drop a content provider from a ProcessRecord's bookkeeping
6688     * @param cpr
6689     */
6690    public void removeContentProvider(IBinder connection, boolean stable) {
6691        enforceNotIsolatedCaller("removeContentProvider");
6692        synchronized (this) {
6693            ContentProviderConnection conn;
6694            try {
6695                conn = (ContentProviderConnection)connection;
6696            } catch (ClassCastException e) {
6697                String msg ="removeContentProvider: " + connection
6698                        + " not a ContentProviderConnection";
6699                Slog.w(TAG, msg);
6700                throw new IllegalArgumentException(msg);
6701            }
6702            if (conn == null) {
6703                throw new NullPointerException("connection is null");
6704            }
6705            if (decProviderCountLocked(conn, null, null, stable)) {
6706                updateOomAdjLocked();
6707            }
6708        }
6709    }
6710
6711    public void removeContentProviderExternal(String name, IBinder token) {
6712        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6713            "Do not have permission in call removeContentProviderExternal()");
6714        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6715    }
6716
6717    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6718        synchronized (this) {
6719            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6720            if(cpr == null) {
6721                //remove from mProvidersByClass
6722                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6723                return;
6724            }
6725
6726            //update content provider record entry info
6727            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6728            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6729            if (localCpr.hasExternalProcessHandles()) {
6730                if (localCpr.removeExternalProcessHandleLocked(token)) {
6731                    updateOomAdjLocked();
6732                } else {
6733                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6734                            + " with no external reference for token: "
6735                            + token + ".");
6736                }
6737            } else {
6738                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6739                        + " with no external references.");
6740            }
6741        }
6742    }
6743
6744    public final void publishContentProviders(IApplicationThread caller,
6745            List<ContentProviderHolder> providers) {
6746        if (providers == null) {
6747            return;
6748        }
6749
6750        enforceNotIsolatedCaller("publishContentProviders");
6751        synchronized (this) {
6752            final ProcessRecord r = getRecordForAppLocked(caller);
6753            if (DEBUG_MU)
6754                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6755            if (r == null) {
6756                throw new SecurityException(
6757                        "Unable to find app for caller " + caller
6758                      + " (pid=" + Binder.getCallingPid()
6759                      + ") when publishing content providers");
6760            }
6761
6762            final long origId = Binder.clearCallingIdentity();
6763
6764            final int N = providers.size();
6765            for (int i=0; i<N; i++) {
6766                ContentProviderHolder src = providers.get(i);
6767                if (src == null || src.info == null || src.provider == null) {
6768                    continue;
6769                }
6770                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6771                if (DEBUG_MU)
6772                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6773                if (dst != null) {
6774                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6775                    mProviderMap.putProviderByClass(comp, dst);
6776                    String names[] = dst.info.authority.split(";");
6777                    for (int j = 0; j < names.length; j++) {
6778                        mProviderMap.putProviderByName(names[j], dst);
6779                    }
6780
6781                    int NL = mLaunchingProviders.size();
6782                    int j;
6783                    for (j=0; j<NL; j++) {
6784                        if (mLaunchingProviders.get(j) == dst) {
6785                            mLaunchingProviders.remove(j);
6786                            j--;
6787                            NL--;
6788                        }
6789                    }
6790                    synchronized (dst) {
6791                        dst.provider = src.provider;
6792                        dst.proc = r;
6793                        dst.notifyAll();
6794                    }
6795                    updateOomAdjLocked(r);
6796                }
6797            }
6798
6799            Binder.restoreCallingIdentity(origId);
6800        }
6801    }
6802
6803    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6804        ContentProviderConnection conn;
6805        try {
6806            conn = (ContentProviderConnection)connection;
6807        } catch (ClassCastException e) {
6808            String msg ="refContentProvider: " + connection
6809                    + " not a ContentProviderConnection";
6810            Slog.w(TAG, msg);
6811            throw new IllegalArgumentException(msg);
6812        }
6813        if (conn == null) {
6814            throw new NullPointerException("connection is null");
6815        }
6816
6817        synchronized (this) {
6818            if (stable > 0) {
6819                conn.numStableIncs += stable;
6820            }
6821            stable = conn.stableCount + stable;
6822            if (stable < 0) {
6823                throw new IllegalStateException("stableCount < 0: " + stable);
6824            }
6825
6826            if (unstable > 0) {
6827                conn.numUnstableIncs += unstable;
6828            }
6829            unstable = conn.unstableCount + unstable;
6830            if (unstable < 0) {
6831                throw new IllegalStateException("unstableCount < 0: " + unstable);
6832            }
6833
6834            if ((stable+unstable) <= 0) {
6835                throw new IllegalStateException("ref counts can't go to zero here: stable="
6836                        + stable + " unstable=" + unstable);
6837            }
6838            conn.stableCount = stable;
6839            conn.unstableCount = unstable;
6840            return !conn.dead;
6841        }
6842    }
6843
6844    public void unstableProviderDied(IBinder connection) {
6845        ContentProviderConnection conn;
6846        try {
6847            conn = (ContentProviderConnection)connection;
6848        } catch (ClassCastException e) {
6849            String msg ="refContentProvider: " + connection
6850                    + " not a ContentProviderConnection";
6851            Slog.w(TAG, msg);
6852            throw new IllegalArgumentException(msg);
6853        }
6854        if (conn == null) {
6855            throw new NullPointerException("connection is null");
6856        }
6857
6858        // Safely retrieve the content provider associated with the connection.
6859        IContentProvider provider;
6860        synchronized (this) {
6861            provider = conn.provider.provider;
6862        }
6863
6864        if (provider == null) {
6865            // Um, yeah, we're way ahead of you.
6866            return;
6867        }
6868
6869        // Make sure the caller is being honest with us.
6870        if (provider.asBinder().pingBinder()) {
6871            // Er, no, still looks good to us.
6872            synchronized (this) {
6873                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6874                        + " says " + conn + " died, but we don't agree");
6875                return;
6876            }
6877        }
6878
6879        // Well look at that!  It's dead!
6880        synchronized (this) {
6881            if (conn.provider.provider != provider) {
6882                // But something changed...  good enough.
6883                return;
6884            }
6885
6886            ProcessRecord proc = conn.provider.proc;
6887            if (proc == null || proc.thread == null) {
6888                // Seems like the process is already cleaned up.
6889                return;
6890            }
6891
6892            // As far as we're concerned, this is just like receiving a
6893            // death notification...  just a bit prematurely.
6894            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6895                    + ") early provider death");
6896            final long ident = Binder.clearCallingIdentity();
6897            try {
6898                appDiedLocked(proc, proc.pid, proc.thread);
6899            } finally {
6900                Binder.restoreCallingIdentity(ident);
6901            }
6902        }
6903    }
6904
6905    public static final void installSystemProviders() {
6906        List<ProviderInfo> providers;
6907        synchronized (mSelf) {
6908            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6909            providers = mSelf.generateApplicationProvidersLocked(app);
6910            if (providers != null) {
6911                for (int i=providers.size()-1; i>=0; i--) {
6912                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6913                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6914                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6915                                + ": not system .apk");
6916                        providers.remove(i);
6917                    }
6918                }
6919            }
6920        }
6921        if (providers != null) {
6922            mSystemThread.installSystemProviders(providers);
6923        }
6924
6925        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6926
6927        mSelf.mUsageStatsService.monitorPackages();
6928    }
6929
6930    /**
6931     * Allows app to retrieve the MIME type of a URI without having permission
6932     * to access its content provider.
6933     *
6934     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6935     *
6936     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6937     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6938     */
6939    public String getProviderMimeType(Uri uri, int userId) {
6940        enforceNotIsolatedCaller("getProviderMimeType");
6941        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6942                userId, false, true, "getProviderMimeType", null);
6943        final String name = uri.getAuthority();
6944        final long ident = Binder.clearCallingIdentity();
6945        ContentProviderHolder holder = null;
6946
6947        try {
6948            holder = getContentProviderExternalUnchecked(name, null, userId);
6949            if (holder != null) {
6950                return holder.provider.getType(uri);
6951            }
6952        } catch (RemoteException e) {
6953            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6954            return null;
6955        } finally {
6956            if (holder != null) {
6957                removeContentProviderExternalUnchecked(name, null, userId);
6958            }
6959            Binder.restoreCallingIdentity(ident);
6960        }
6961
6962        return null;
6963    }
6964
6965    // =========================================================
6966    // GLOBAL MANAGEMENT
6967    // =========================================================
6968
6969    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6970            ApplicationInfo info, String customProcess, boolean isolated) {
6971        String proc = customProcess != null ? customProcess : info.processName;
6972        BatteryStatsImpl.Uid.Proc ps = null;
6973        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6974        int uid = info.uid;
6975        if (isolated) {
6976            int userId = UserHandle.getUserId(uid);
6977            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6978            uid = 0;
6979            while (true) {
6980                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6981                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6982                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6983                }
6984                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6985                mNextIsolatedProcessUid++;
6986                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6987                    // No process for this uid, use it.
6988                    break;
6989                }
6990                stepsLeft--;
6991                if (stepsLeft <= 0) {
6992                    return null;
6993                }
6994            }
6995        }
6996        synchronized (stats) {
6997            ps = stats.getProcessStatsLocked(info.uid, proc);
6998        }
6999        return new ProcessRecord(ps, thread, info, proc, uid);
7000    }
7001
7002    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7003        ProcessRecord app;
7004        if (!isolated) {
7005            app = getProcessRecordLocked(info.processName, info.uid);
7006        } else {
7007            app = null;
7008        }
7009
7010        if (app == null) {
7011            app = newProcessRecordLocked(null, info, null, isolated);
7012            mProcessNames.put(info.processName, app.uid, app);
7013            if (isolated) {
7014                mIsolatedProcesses.put(app.uid, app);
7015            }
7016            updateLruProcessLocked(app, true, true);
7017        }
7018
7019        // This package really, really can not be stopped.
7020        try {
7021            AppGlobals.getPackageManager().setPackageStoppedState(
7022                    info.packageName, false, UserHandle.getUserId(app.uid));
7023        } catch (RemoteException e) {
7024        } catch (IllegalArgumentException e) {
7025            Slog.w(TAG, "Failed trying to unstop package "
7026                    + info.packageName + ": " + e);
7027        }
7028
7029        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7030                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7031            app.persistent = true;
7032            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7033        }
7034        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7035            mPersistentStartingProcesses.add(app);
7036            startProcessLocked(app, "added application", app.processName);
7037        }
7038
7039        return app;
7040    }
7041
7042    public void unhandledBack() {
7043        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7044                "unhandledBack()");
7045
7046        synchronized(this) {
7047            int count = mMainStack.mHistory.size();
7048            if (DEBUG_SWITCH) Slog.d(
7049                TAG, "Performing unhandledBack(): stack size = " + count);
7050            if (count > 1) {
7051                final long origId = Binder.clearCallingIdentity();
7052                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7053                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7054                Binder.restoreCallingIdentity(origId);
7055            }
7056        }
7057    }
7058
7059    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7060        enforceNotIsolatedCaller("openContentUri");
7061        final int userId = UserHandle.getCallingUserId();
7062        String name = uri.getAuthority();
7063        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7064        ParcelFileDescriptor pfd = null;
7065        if (cph != null) {
7066            // We record the binder invoker's uid in thread-local storage before
7067            // going to the content provider to open the file.  Later, in the code
7068            // that handles all permissions checks, we look for this uid and use
7069            // that rather than the Activity Manager's own uid.  The effect is that
7070            // we do the check against the caller's permissions even though it looks
7071            // to the content provider like the Activity Manager itself is making
7072            // the request.
7073            sCallerIdentity.set(new Identity(
7074                    Binder.getCallingPid(), Binder.getCallingUid()));
7075            try {
7076                pfd = cph.provider.openFile(uri, "r");
7077            } catch (FileNotFoundException e) {
7078                // do nothing; pfd will be returned null
7079            } finally {
7080                // Ensure that whatever happens, we clean up the identity state
7081                sCallerIdentity.remove();
7082            }
7083
7084            // We've got the fd now, so we're done with the provider.
7085            removeContentProviderExternalUnchecked(name, null, userId);
7086        } else {
7087            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7088        }
7089        return pfd;
7090    }
7091
7092    // Actually is sleeping or shutting down or whatever else in the future
7093    // is an inactive state.
7094    public boolean isSleeping() {
7095        return mSleeping || mShuttingDown;
7096    }
7097
7098    public void goingToSleep() {
7099        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7100                != PackageManager.PERMISSION_GRANTED) {
7101            throw new SecurityException("Requires permission "
7102                    + android.Manifest.permission.DEVICE_POWER);
7103        }
7104
7105        synchronized(this) {
7106            mWentToSleep = true;
7107            updateEventDispatchingLocked();
7108
7109            if (!mSleeping) {
7110                mSleeping = true;
7111                mMainStack.stopIfSleepingLocked();
7112
7113                // Initialize the wake times of all processes.
7114                checkExcessivePowerUsageLocked(false);
7115                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7116                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7117                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7118            }
7119        }
7120    }
7121
7122    public boolean shutdown(int timeout) {
7123        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7124                != PackageManager.PERMISSION_GRANTED) {
7125            throw new SecurityException("Requires permission "
7126                    + android.Manifest.permission.SHUTDOWN);
7127        }
7128
7129        boolean timedout = false;
7130
7131        synchronized(this) {
7132            mShuttingDown = true;
7133            updateEventDispatchingLocked();
7134
7135            if (mMainStack.mResumedActivity != null) {
7136                mMainStack.stopIfSleepingLocked();
7137                final long endTime = System.currentTimeMillis() + timeout;
7138                while (mMainStack.mResumedActivity != null
7139                        || mMainStack.mPausingActivity != null) {
7140                    long delay = endTime - System.currentTimeMillis();
7141                    if (delay <= 0) {
7142                        Slog.w(TAG, "Activity manager shutdown timed out");
7143                        timedout = true;
7144                        break;
7145                    }
7146                    try {
7147                        this.wait();
7148                    } catch (InterruptedException e) {
7149                    }
7150                }
7151            }
7152        }
7153
7154        mUsageStatsService.shutdown();
7155        mBatteryStatsService.shutdown();
7156
7157        return timedout;
7158    }
7159
7160    public final void activitySlept(IBinder token) {
7161        if (localLOGV) Slog.v(
7162            TAG, "Activity slept: token=" + token);
7163
7164        ActivityRecord r = null;
7165
7166        final long origId = Binder.clearCallingIdentity();
7167
7168        synchronized (this) {
7169            r = mMainStack.isInStackLocked(token);
7170            if (r != null) {
7171                mMainStack.activitySleptLocked(r);
7172            }
7173        }
7174
7175        Binder.restoreCallingIdentity(origId);
7176    }
7177
7178    private void comeOutOfSleepIfNeededLocked() {
7179        if (!mWentToSleep && !mLockScreenShown) {
7180            if (mSleeping) {
7181                mSleeping = false;
7182                mMainStack.awakeFromSleepingLocked();
7183                mMainStack.resumeTopActivityLocked(null);
7184            }
7185        }
7186    }
7187
7188    public void wakingUp() {
7189        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7190                != PackageManager.PERMISSION_GRANTED) {
7191            throw new SecurityException("Requires permission "
7192                    + android.Manifest.permission.DEVICE_POWER);
7193        }
7194
7195        synchronized(this) {
7196            mWentToSleep = false;
7197            updateEventDispatchingLocked();
7198            comeOutOfSleepIfNeededLocked();
7199        }
7200    }
7201
7202    private void updateEventDispatchingLocked() {
7203        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7204    }
7205
7206    public void setLockScreenShown(boolean shown) {
7207        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7208                != PackageManager.PERMISSION_GRANTED) {
7209            throw new SecurityException("Requires permission "
7210                    + android.Manifest.permission.DEVICE_POWER);
7211        }
7212
7213        synchronized(this) {
7214            mLockScreenShown = shown;
7215            comeOutOfSleepIfNeededLocked();
7216        }
7217    }
7218
7219    public void stopAppSwitches() {
7220        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7221                != PackageManager.PERMISSION_GRANTED) {
7222            throw new SecurityException("Requires permission "
7223                    + android.Manifest.permission.STOP_APP_SWITCHES);
7224        }
7225
7226        synchronized(this) {
7227            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7228                    + APP_SWITCH_DELAY_TIME;
7229            mDidAppSwitch = false;
7230            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7231            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7232            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7233        }
7234    }
7235
7236    public void resumeAppSwitches() {
7237        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7238                != PackageManager.PERMISSION_GRANTED) {
7239            throw new SecurityException("Requires permission "
7240                    + android.Manifest.permission.STOP_APP_SWITCHES);
7241        }
7242
7243        synchronized(this) {
7244            // Note that we don't execute any pending app switches... we will
7245            // let those wait until either the timeout, or the next start
7246            // activity request.
7247            mAppSwitchesAllowedTime = 0;
7248        }
7249    }
7250
7251    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7252            String name) {
7253        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7254            return true;
7255        }
7256
7257        final int perm = checkComponentPermission(
7258                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7259                callingUid, -1, true);
7260        if (perm == PackageManager.PERMISSION_GRANTED) {
7261            return true;
7262        }
7263
7264        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7265        return false;
7266    }
7267
7268    public void setDebugApp(String packageName, boolean waitForDebugger,
7269            boolean persistent) {
7270        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7271                "setDebugApp()");
7272
7273        // Note that this is not really thread safe if there are multiple
7274        // callers into it at the same time, but that's not a situation we
7275        // care about.
7276        if (persistent) {
7277            final ContentResolver resolver = mContext.getContentResolver();
7278            Settings.System.putString(
7279                resolver, Settings.System.DEBUG_APP,
7280                packageName);
7281            Settings.System.putInt(
7282                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7283                waitForDebugger ? 1 : 0);
7284        }
7285
7286        synchronized (this) {
7287            if (!persistent) {
7288                mOrigDebugApp = mDebugApp;
7289                mOrigWaitForDebugger = mWaitForDebugger;
7290            }
7291            mDebugApp = packageName;
7292            mWaitForDebugger = waitForDebugger;
7293            mDebugTransient = !persistent;
7294            if (packageName != null) {
7295                final long origId = Binder.clearCallingIdentity();
7296                forceStopPackageLocked(packageName, -1, false, false, true, true,
7297                        UserHandle.USER_ALL);
7298                Binder.restoreCallingIdentity(origId);
7299            }
7300        }
7301    }
7302
7303    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7304        synchronized (this) {
7305            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7306            if (!isDebuggable) {
7307                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7308                    throw new SecurityException("Process not debuggable: " + app.packageName);
7309                }
7310            }
7311
7312            mOpenGlTraceApp = processName;
7313        }
7314    }
7315
7316    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7317            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7318        synchronized (this) {
7319            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7320            if (!isDebuggable) {
7321                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7322                    throw new SecurityException("Process not debuggable: " + app.packageName);
7323                }
7324            }
7325            mProfileApp = processName;
7326            mProfileFile = profileFile;
7327            if (mProfileFd != null) {
7328                try {
7329                    mProfileFd.close();
7330                } catch (IOException e) {
7331                }
7332                mProfileFd = null;
7333            }
7334            mProfileFd = profileFd;
7335            mProfileType = 0;
7336            mAutoStopProfiler = autoStopProfiler;
7337        }
7338    }
7339
7340    public void setAlwaysFinish(boolean enabled) {
7341        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7342                "setAlwaysFinish()");
7343
7344        Settings.System.putInt(
7345                mContext.getContentResolver(),
7346                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7347
7348        synchronized (this) {
7349            mAlwaysFinishActivities = enabled;
7350        }
7351    }
7352
7353    public void setActivityController(IActivityController controller) {
7354        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7355                "setActivityController()");
7356        synchronized (this) {
7357            mController = controller;
7358        }
7359    }
7360
7361    public boolean isUserAMonkey() {
7362        // For now the fact that there is a controller implies
7363        // we have a monkey.
7364        synchronized (this) {
7365            return mController != null;
7366        }
7367    }
7368
7369    public void registerProcessObserver(IProcessObserver observer) {
7370        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7371                "registerProcessObserver()");
7372        synchronized (this) {
7373            mProcessObservers.register(observer);
7374        }
7375    }
7376
7377    public void unregisterProcessObserver(IProcessObserver observer) {
7378        synchronized (this) {
7379            mProcessObservers.unregister(observer);
7380        }
7381    }
7382
7383    public void setImmersive(IBinder token, boolean immersive) {
7384        synchronized(this) {
7385            ActivityRecord r = mMainStack.isInStackLocked(token);
7386            if (r == null) {
7387                throw new IllegalArgumentException();
7388            }
7389            r.immersive = immersive;
7390        }
7391    }
7392
7393    public boolean isImmersive(IBinder token) {
7394        synchronized (this) {
7395            ActivityRecord r = mMainStack.isInStackLocked(token);
7396            if (r == null) {
7397                throw new IllegalArgumentException();
7398            }
7399            return r.immersive;
7400        }
7401    }
7402
7403    public boolean isTopActivityImmersive() {
7404        enforceNotIsolatedCaller("startActivity");
7405        synchronized (this) {
7406            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7407            return (r != null) ? r.immersive : false;
7408        }
7409    }
7410
7411    public final void enterSafeMode() {
7412        synchronized(this) {
7413            // It only makes sense to do this before the system is ready
7414            // and started launching other packages.
7415            if (!mSystemReady) {
7416                try {
7417                    AppGlobals.getPackageManager().enterSafeMode();
7418                } catch (RemoteException e) {
7419                }
7420            }
7421        }
7422    }
7423
7424    public final void showSafeModeOverlay() {
7425        View v = LayoutInflater.from(mContext).inflate(
7426                com.android.internal.R.layout.safe_mode, null);
7427        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7428        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7429        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7430        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7431        lp.gravity = Gravity.BOTTOM | Gravity.START;
7432        lp.format = v.getBackground().getOpacity();
7433        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7434                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7435        ((WindowManager)mContext.getSystemService(
7436                Context.WINDOW_SERVICE)).addView(v, lp);
7437    }
7438
7439    public void noteWakeupAlarm(IIntentSender sender) {
7440        if (!(sender instanceof PendingIntentRecord)) {
7441            return;
7442        }
7443        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7444        synchronized (stats) {
7445            if (mBatteryStatsService.isOnBattery()) {
7446                mBatteryStatsService.enforceCallingPermission();
7447                PendingIntentRecord rec = (PendingIntentRecord)sender;
7448                int MY_UID = Binder.getCallingUid();
7449                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7450                BatteryStatsImpl.Uid.Pkg pkg =
7451                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7452                pkg.incWakeupsLocked();
7453            }
7454        }
7455    }
7456
7457    public boolean killPids(int[] pids, String pReason, boolean secure) {
7458        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7459            throw new SecurityException("killPids only available to the system");
7460        }
7461        String reason = (pReason == null) ? "Unknown" : pReason;
7462        // XXX Note: don't acquire main activity lock here, because the window
7463        // manager calls in with its locks held.
7464
7465        boolean killed = false;
7466        synchronized (mPidsSelfLocked) {
7467            int[] types = new int[pids.length];
7468            int worstType = 0;
7469            for (int i=0; i<pids.length; i++) {
7470                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7471                if (proc != null) {
7472                    int type = proc.setAdj;
7473                    types[i] = type;
7474                    if (type > worstType) {
7475                        worstType = type;
7476                    }
7477                }
7478            }
7479
7480            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7481            // then constrain it so we will kill all hidden procs.
7482            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7483                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7484                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7485            }
7486
7487            // If this is not a secure call, don't let it kill processes that
7488            // are important.
7489            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7490                worstType = ProcessList.SERVICE_ADJ;
7491            }
7492
7493            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7494            for (int i=0; i<pids.length; i++) {
7495                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7496                if (proc == null) {
7497                    continue;
7498                }
7499                int adj = proc.setAdj;
7500                if (adj >= worstType && !proc.killedBackground) {
7501                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7502                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7503                            proc.processName, adj, reason);
7504                    killed = true;
7505                    proc.killedBackground = true;
7506                    Process.killProcessQuiet(pids[i]);
7507                }
7508            }
7509        }
7510        return killed;
7511    }
7512
7513    @Override
7514    public boolean killProcessesBelowForeground(String reason) {
7515        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7516            throw new SecurityException("killProcessesBelowForeground() only available to system");
7517        }
7518
7519        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7520    }
7521
7522    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7523        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7524            throw new SecurityException("killProcessesBelowAdj() only available to system");
7525        }
7526
7527        boolean killed = false;
7528        synchronized (mPidsSelfLocked) {
7529            final int size = mPidsSelfLocked.size();
7530            for (int i = 0; i < size; i++) {
7531                final int pid = mPidsSelfLocked.keyAt(i);
7532                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7533                if (proc == null) continue;
7534
7535                final int adj = proc.setAdj;
7536                if (adj > belowAdj && !proc.killedBackground) {
7537                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7538                    EventLog.writeEvent(
7539                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7540                    killed = true;
7541                    proc.killedBackground = true;
7542                    Process.killProcessQuiet(pid);
7543                }
7544            }
7545        }
7546        return killed;
7547    }
7548
7549    public final void startRunning(String pkg, String cls, String action,
7550            String data) {
7551        synchronized(this) {
7552            if (mStartRunning) {
7553                return;
7554            }
7555            mStartRunning = true;
7556            mTopComponent = pkg != null && cls != null
7557                    ? new ComponentName(pkg, cls) : null;
7558            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7559            mTopData = data;
7560            if (!mSystemReady) {
7561                return;
7562            }
7563        }
7564
7565        systemReady(null);
7566    }
7567
7568    private void retrieveSettings() {
7569        final ContentResolver resolver = mContext.getContentResolver();
7570        String debugApp = Settings.System.getString(
7571            resolver, Settings.System.DEBUG_APP);
7572        boolean waitForDebugger = Settings.System.getInt(
7573            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7574        boolean alwaysFinishActivities = Settings.System.getInt(
7575            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7576
7577        Configuration configuration = new Configuration();
7578        Settings.System.getConfiguration(resolver, configuration);
7579
7580        synchronized (this) {
7581            mDebugApp = mOrigDebugApp = debugApp;
7582            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7583            mAlwaysFinishActivities = alwaysFinishActivities;
7584            // This happens before any activities are started, so we can
7585            // change mConfiguration in-place.
7586            updateConfigurationLocked(configuration, null, false, true);
7587            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7588        }
7589    }
7590
7591    public boolean testIsSystemReady() {
7592        // no need to synchronize(this) just to read & return the value
7593        return mSystemReady;
7594    }
7595
7596    private static File getCalledPreBootReceiversFile() {
7597        File dataDir = Environment.getDataDirectory();
7598        File systemDir = new File(dataDir, "system");
7599        File fname = new File(systemDir, "called_pre_boots.dat");
7600        return fname;
7601    }
7602
7603    static final int LAST_DONE_VERSION = 10000;
7604
7605    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7606        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7607        File file = getCalledPreBootReceiversFile();
7608        FileInputStream fis = null;
7609        try {
7610            fis = new FileInputStream(file);
7611            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7612            int fvers = dis.readInt();
7613            if (fvers == LAST_DONE_VERSION) {
7614                String vers = dis.readUTF();
7615                String codename = dis.readUTF();
7616                String build = dis.readUTF();
7617                if (android.os.Build.VERSION.RELEASE.equals(vers)
7618                        && android.os.Build.VERSION.CODENAME.equals(codename)
7619                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7620                    int num = dis.readInt();
7621                    while (num > 0) {
7622                        num--;
7623                        String pkg = dis.readUTF();
7624                        String cls = dis.readUTF();
7625                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7626                    }
7627                }
7628            }
7629        } catch (FileNotFoundException e) {
7630        } catch (IOException e) {
7631            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7632        } finally {
7633            if (fis != null) {
7634                try {
7635                    fis.close();
7636                } catch (IOException e) {
7637                }
7638            }
7639        }
7640        return lastDoneReceivers;
7641    }
7642
7643    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7644        File file = getCalledPreBootReceiversFile();
7645        FileOutputStream fos = null;
7646        DataOutputStream dos = null;
7647        try {
7648            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7649            fos = new FileOutputStream(file);
7650            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7651            dos.writeInt(LAST_DONE_VERSION);
7652            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7653            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7654            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7655            dos.writeInt(list.size());
7656            for (int i=0; i<list.size(); i++) {
7657                dos.writeUTF(list.get(i).getPackageName());
7658                dos.writeUTF(list.get(i).getClassName());
7659            }
7660        } catch (IOException e) {
7661            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7662            file.delete();
7663        } finally {
7664            FileUtils.sync(fos);
7665            if (dos != null) {
7666                try {
7667                    dos.close();
7668                } catch (IOException e) {
7669                    // TODO Auto-generated catch block
7670                    e.printStackTrace();
7671                }
7672            }
7673        }
7674    }
7675
7676    public void systemReady(final Runnable goingCallback) {
7677        synchronized(this) {
7678            if (mSystemReady) {
7679                if (goingCallback != null) goingCallback.run();
7680                return;
7681            }
7682
7683            // Check to see if there are any update receivers to run.
7684            if (!mDidUpdate) {
7685                if (mWaitingUpdate) {
7686                    return;
7687                }
7688                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7689                List<ResolveInfo> ris = null;
7690                try {
7691                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7692                            intent, null, 0, 0);
7693                } catch (RemoteException e) {
7694                }
7695                if (ris != null) {
7696                    for (int i=ris.size()-1; i>=0; i--) {
7697                        if ((ris.get(i).activityInfo.applicationInfo.flags
7698                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7699                            ris.remove(i);
7700                        }
7701                    }
7702                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7703
7704                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7705
7706                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7707                    for (int i=0; i<ris.size(); i++) {
7708                        ActivityInfo ai = ris.get(i).activityInfo;
7709                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7710                        if (lastDoneReceivers.contains(comp)) {
7711                            ris.remove(i);
7712                            i--;
7713                        }
7714                    }
7715
7716                    final int[] users = getUsersLocked();
7717                    for (int i=0; i<ris.size(); i++) {
7718                        ActivityInfo ai = ris.get(i).activityInfo;
7719                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7720                        doneReceivers.add(comp);
7721                        intent.setComponent(comp);
7722                        for (int j=0; j<users.length; j++) {
7723                            IIntentReceiver finisher = null;
7724                            if (i == ris.size()-1 && j == users.length-1) {
7725                                finisher = new IIntentReceiver.Stub() {
7726                                    public void performReceive(Intent intent, int resultCode,
7727                                            String data, Bundle extras, boolean ordered,
7728                                            boolean sticky, int sendingUser) {
7729                                        // The raw IIntentReceiver interface is called
7730                                        // with the AM lock held, so redispatch to
7731                                        // execute our code without the lock.
7732                                        mHandler.post(new Runnable() {
7733                                            public void run() {
7734                                                synchronized (ActivityManagerService.this) {
7735                                                    mDidUpdate = true;
7736                                                }
7737                                                writeLastDonePreBootReceivers(doneReceivers);
7738                                                showBootMessage(mContext.getText(
7739                                                        R.string.android_upgrading_complete),
7740                                                        false);
7741                                                systemReady(goingCallback);
7742                                            }
7743                                        });
7744                                    }
7745                                };
7746                            }
7747                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7748                                    + " for user " + users[j]);
7749                            broadcastIntentLocked(null, null, intent, null, finisher,
7750                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7751                                    users[j]);
7752                            if (finisher != null) {
7753                                mWaitingUpdate = true;
7754                            }
7755                        }
7756                    }
7757                }
7758                if (mWaitingUpdate) {
7759                    return;
7760                }
7761                mDidUpdate = true;
7762            }
7763
7764            mSystemReady = true;
7765            if (!mStartRunning) {
7766                return;
7767            }
7768        }
7769
7770        ArrayList<ProcessRecord> procsToKill = null;
7771        synchronized(mPidsSelfLocked) {
7772            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7773                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7774                if (!isAllowedWhileBooting(proc.info)){
7775                    if (procsToKill == null) {
7776                        procsToKill = new ArrayList<ProcessRecord>();
7777                    }
7778                    procsToKill.add(proc);
7779                }
7780            }
7781        }
7782
7783        synchronized(this) {
7784            if (procsToKill != null) {
7785                for (int i=procsToKill.size()-1; i>=0; i--) {
7786                    ProcessRecord proc = procsToKill.get(i);
7787                    Slog.i(TAG, "Removing system update proc: " + proc);
7788                    removeProcessLocked(proc, true, false, "system update done");
7789                }
7790            }
7791
7792            // Now that we have cleaned up any update processes, we
7793            // are ready to start launching real processes and know that
7794            // we won't trample on them any more.
7795            mProcessesReady = true;
7796        }
7797
7798        Slog.i(TAG, "System now ready");
7799        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7800            SystemClock.uptimeMillis());
7801
7802        synchronized(this) {
7803            // Make sure we have no pre-ready processes sitting around.
7804
7805            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7806                ResolveInfo ri = mContext.getPackageManager()
7807                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7808                                STOCK_PM_FLAGS);
7809                CharSequence errorMsg = null;
7810                if (ri != null) {
7811                    ActivityInfo ai = ri.activityInfo;
7812                    ApplicationInfo app = ai.applicationInfo;
7813                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7814                        mTopAction = Intent.ACTION_FACTORY_TEST;
7815                        mTopData = null;
7816                        mTopComponent = new ComponentName(app.packageName,
7817                                ai.name);
7818                    } else {
7819                        errorMsg = mContext.getResources().getText(
7820                                com.android.internal.R.string.factorytest_not_system);
7821                    }
7822                } else {
7823                    errorMsg = mContext.getResources().getText(
7824                            com.android.internal.R.string.factorytest_no_action);
7825                }
7826                if (errorMsg != null) {
7827                    mTopAction = null;
7828                    mTopData = null;
7829                    mTopComponent = null;
7830                    Message msg = Message.obtain();
7831                    msg.what = SHOW_FACTORY_ERROR_MSG;
7832                    msg.getData().putCharSequence("msg", errorMsg);
7833                    mHandler.sendMessage(msg);
7834                }
7835            }
7836        }
7837
7838        retrieveSettings();
7839
7840        if (goingCallback != null) goingCallback.run();
7841
7842        synchronized (this) {
7843            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7844                try {
7845                    List apps = AppGlobals.getPackageManager().
7846                        getPersistentApplications(STOCK_PM_FLAGS);
7847                    if (apps != null) {
7848                        int N = apps.size();
7849                        int i;
7850                        for (i=0; i<N; i++) {
7851                            ApplicationInfo info
7852                                = (ApplicationInfo)apps.get(i);
7853                            if (info != null &&
7854                                    !info.packageName.equals("android")) {
7855                                addAppLocked(info, false);
7856                            }
7857                        }
7858                    }
7859                } catch (RemoteException ex) {
7860                    // pm is in same process, this will never happen.
7861                }
7862            }
7863
7864            // Start up initial activity.
7865            mBooting = true;
7866
7867            try {
7868                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7869                    Message msg = Message.obtain();
7870                    msg.what = SHOW_UID_ERROR_MSG;
7871                    mHandler.sendMessage(msg);
7872                }
7873            } catch (RemoteException e) {
7874            }
7875
7876            long ident = Binder.clearCallingIdentity();
7877            try {
7878                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7879                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7880                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7881                broadcastIntentLocked(null, null, intent,
7882                        null, null, 0, null, null, null,
7883                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7884            } finally {
7885                Binder.restoreCallingIdentity(ident);
7886            }
7887            mMainStack.resumeTopActivityLocked(null);
7888            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7889        }
7890    }
7891
7892    private boolean makeAppCrashingLocked(ProcessRecord app,
7893            String shortMsg, String longMsg, String stackTrace) {
7894        app.crashing = true;
7895        app.crashingReport = generateProcessError(app,
7896                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7897        startAppProblemLocked(app);
7898        app.stopFreezingAllLocked();
7899        return handleAppCrashLocked(app);
7900    }
7901
7902    private void makeAppNotRespondingLocked(ProcessRecord app,
7903            String activity, String shortMsg, String longMsg) {
7904        app.notResponding = true;
7905        app.notRespondingReport = generateProcessError(app,
7906                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7907                activity, shortMsg, longMsg, null);
7908        startAppProblemLocked(app);
7909        app.stopFreezingAllLocked();
7910    }
7911
7912    /**
7913     * Generate a process error record, suitable for attachment to a ProcessRecord.
7914     *
7915     * @param app The ProcessRecord in which the error occurred.
7916     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7917     *                      ActivityManager.AppErrorStateInfo
7918     * @param activity The activity associated with the crash, if known.
7919     * @param shortMsg Short message describing the crash.
7920     * @param longMsg Long message describing the crash.
7921     * @param stackTrace Full crash stack trace, may be null.
7922     *
7923     * @return Returns a fully-formed AppErrorStateInfo record.
7924     */
7925    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7926            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7927        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7928
7929        report.condition = condition;
7930        report.processName = app.processName;
7931        report.pid = app.pid;
7932        report.uid = app.info.uid;
7933        report.tag = activity;
7934        report.shortMsg = shortMsg;
7935        report.longMsg = longMsg;
7936        report.stackTrace = stackTrace;
7937
7938        return report;
7939    }
7940
7941    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7942        synchronized (this) {
7943            app.crashing = false;
7944            app.crashingReport = null;
7945            app.notResponding = false;
7946            app.notRespondingReport = null;
7947            if (app.anrDialog == fromDialog) {
7948                app.anrDialog = null;
7949            }
7950            if (app.waitDialog == fromDialog) {
7951                app.waitDialog = null;
7952            }
7953            if (app.pid > 0 && app.pid != MY_PID) {
7954                handleAppCrashLocked(app);
7955                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7956                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7957                        app.processName, app.setAdj, "user's request after error");
7958                Process.killProcessQuiet(app.pid);
7959            }
7960        }
7961    }
7962
7963    private boolean handleAppCrashLocked(ProcessRecord app) {
7964        if (mHeadless) {
7965            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7966            return false;
7967        }
7968        long now = SystemClock.uptimeMillis();
7969
7970        Long crashTime;
7971        if (!app.isolated) {
7972            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7973        } else {
7974            crashTime = null;
7975        }
7976        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7977            // This process loses!
7978            Slog.w(TAG, "Process " + app.info.processName
7979                    + " has crashed too many times: killing!");
7980            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7981                    app.info.processName, app.uid);
7982            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7983                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7984                if (r.app == app) {
7985                    Slog.w(TAG, "  Force finishing activity "
7986                        + r.intent.getComponent().flattenToShortString());
7987                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7988                            null, "crashed", false);
7989                }
7990            }
7991            if (!app.persistent) {
7992                // We don't want to start this process again until the user
7993                // explicitly does so...  but for persistent process, we really
7994                // need to keep it running.  If a persistent process is actually
7995                // repeatedly crashing, then badness for everyone.
7996                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7997                        app.info.processName);
7998                if (!app.isolated) {
7999                    // XXX We don't have a way to mark isolated processes
8000                    // as bad, since they don't have a peristent identity.
8001                    mBadProcesses.put(app.info.processName, app.uid, now);
8002                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8003                }
8004                app.bad = true;
8005                app.removed = true;
8006                // Don't let services in this process be restarted and potentially
8007                // annoy the user repeatedly.  Unless it is persistent, since those
8008                // processes run critical code.
8009                removeProcessLocked(app, false, false, "crash");
8010                mMainStack.resumeTopActivityLocked(null);
8011                return false;
8012            }
8013            mMainStack.resumeTopActivityLocked(null);
8014        } else {
8015            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8016            if (r != null && r.app == app) {
8017                // If the top running activity is from this crashing
8018                // process, then terminate it to avoid getting in a loop.
8019                Slog.w(TAG, "  Force finishing activity "
8020                        + r.intent.getComponent().flattenToShortString());
8021                int index = mMainStack.indexOfActivityLocked(r);
8022                r.stack.finishActivityLocked(r, index,
8023                        Activity.RESULT_CANCELED, null, "crashed", false);
8024                // Also terminate any activities below it that aren't yet
8025                // stopped, to avoid a situation where one will get
8026                // re-start our crashing activity once it gets resumed again.
8027                index--;
8028                if (index >= 0) {
8029                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8030                    if (r.state == ActivityState.RESUMED
8031                            || r.state == ActivityState.PAUSING
8032                            || r.state == ActivityState.PAUSED) {
8033                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8034                            Slog.w(TAG, "  Force finishing activity "
8035                                    + r.intent.getComponent().flattenToShortString());
8036                            r.stack.finishActivityLocked(r, index,
8037                                    Activity.RESULT_CANCELED, null, "crashed", false);
8038                        }
8039                    }
8040                }
8041            }
8042        }
8043
8044        // Bump up the crash count of any services currently running in the proc.
8045        if (app.services.size() != 0) {
8046            // Any services running in the application need to be placed
8047            // back in the pending list.
8048            Iterator<ServiceRecord> it = app.services.iterator();
8049            while (it.hasNext()) {
8050                ServiceRecord sr = it.next();
8051                sr.crashCount++;
8052            }
8053        }
8054
8055        // If the crashing process is what we consider to be the "home process" and it has been
8056        // replaced by a third-party app, clear the package preferred activities from packages
8057        // with a home activity running in the process to prevent a repeatedly crashing app
8058        // from blocking the user to manually clear the list.
8059        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8060                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8061            Iterator it = mHomeProcess.activities.iterator();
8062            while (it.hasNext()) {
8063                ActivityRecord r = (ActivityRecord)it.next();
8064                if (r.isHomeActivity) {
8065                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8066                    try {
8067                        ActivityThread.getPackageManager()
8068                                .clearPackagePreferredActivities(r.packageName);
8069                    } catch (RemoteException c) {
8070                        // pm is in same process, this will never happen.
8071                    }
8072                }
8073            }
8074        }
8075
8076        if (!app.isolated) {
8077            // XXX Can't keep track of crash times for isolated processes,
8078            // because they don't have a perisistent identity.
8079            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8080        }
8081
8082        return true;
8083    }
8084
8085    void startAppProblemLocked(ProcessRecord app) {
8086        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8087                mContext, app.info.packageName, app.info.flags);
8088        skipCurrentReceiverLocked(app);
8089    }
8090
8091    void skipCurrentReceiverLocked(ProcessRecord app) {
8092        for (BroadcastQueue queue : mBroadcastQueues) {
8093            queue.skipCurrentReceiverLocked(app);
8094        }
8095    }
8096
8097    /**
8098     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8099     * The application process will exit immediately after this call returns.
8100     * @param app object of the crashing app, null for the system server
8101     * @param crashInfo describing the exception
8102     */
8103    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8104        ProcessRecord r = findAppProcess(app, "Crash");
8105        final String processName = app == null ? "system_server"
8106                : (r == null ? "unknown" : r.processName);
8107
8108        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8109                processName,
8110                r == null ? -1 : r.info.flags,
8111                crashInfo.exceptionClassName,
8112                crashInfo.exceptionMessage,
8113                crashInfo.throwFileName,
8114                crashInfo.throwLineNumber);
8115
8116        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8117
8118        crashApplication(r, crashInfo);
8119    }
8120
8121    public void handleApplicationStrictModeViolation(
8122            IBinder app,
8123            int violationMask,
8124            StrictMode.ViolationInfo info) {
8125        ProcessRecord r = findAppProcess(app, "StrictMode");
8126        if (r == null) {
8127            return;
8128        }
8129
8130        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8131            Integer stackFingerprint = info.hashCode();
8132            boolean logIt = true;
8133            synchronized (mAlreadyLoggedViolatedStacks) {
8134                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8135                    logIt = false;
8136                    // TODO: sub-sample into EventLog for these, with
8137                    // the info.durationMillis?  Then we'd get
8138                    // the relative pain numbers, without logging all
8139                    // the stack traces repeatedly.  We'd want to do
8140                    // likewise in the client code, which also does
8141                    // dup suppression, before the Binder call.
8142                } else {
8143                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8144                        mAlreadyLoggedViolatedStacks.clear();
8145                    }
8146                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8147                }
8148            }
8149            if (logIt) {
8150                logStrictModeViolationToDropBox(r, info);
8151            }
8152        }
8153
8154        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8155            AppErrorResult result = new AppErrorResult();
8156            synchronized (this) {
8157                final long origId = Binder.clearCallingIdentity();
8158
8159                Message msg = Message.obtain();
8160                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8161                HashMap<String, Object> data = new HashMap<String, Object>();
8162                data.put("result", result);
8163                data.put("app", r);
8164                data.put("violationMask", violationMask);
8165                data.put("info", info);
8166                msg.obj = data;
8167                mHandler.sendMessage(msg);
8168
8169                Binder.restoreCallingIdentity(origId);
8170            }
8171            int res = result.get();
8172            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8173        }
8174    }
8175
8176    // Depending on the policy in effect, there could be a bunch of
8177    // these in quick succession so we try to batch these together to
8178    // minimize disk writes, number of dropbox entries, and maximize
8179    // compression, by having more fewer, larger records.
8180    private void logStrictModeViolationToDropBox(
8181            ProcessRecord process,
8182            StrictMode.ViolationInfo info) {
8183        if (info == null) {
8184            return;
8185        }
8186        final boolean isSystemApp = process == null ||
8187                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8188                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8189        final String processName = process == null ? "unknown" : process.processName;
8190        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8191        final DropBoxManager dbox = (DropBoxManager)
8192                mContext.getSystemService(Context.DROPBOX_SERVICE);
8193
8194        // Exit early if the dropbox isn't configured to accept this report type.
8195        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8196
8197        boolean bufferWasEmpty;
8198        boolean needsFlush;
8199        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8200        synchronized (sb) {
8201            bufferWasEmpty = sb.length() == 0;
8202            appendDropBoxProcessHeaders(process, processName, sb);
8203            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8204            sb.append("System-App: ").append(isSystemApp).append("\n");
8205            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8206            if (info.violationNumThisLoop != 0) {
8207                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8208            }
8209            if (info.numAnimationsRunning != 0) {
8210                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8211            }
8212            if (info.broadcastIntentAction != null) {
8213                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8214            }
8215            if (info.durationMillis != -1) {
8216                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8217            }
8218            if (info.numInstances != -1) {
8219                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8220            }
8221            if (info.tags != null) {
8222                for (String tag : info.tags) {
8223                    sb.append("Span-Tag: ").append(tag).append("\n");
8224                }
8225            }
8226            sb.append("\n");
8227            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8228                sb.append(info.crashInfo.stackTrace);
8229            }
8230            sb.append("\n");
8231
8232            // Only buffer up to ~64k.  Various logging bits truncate
8233            // things at 128k.
8234            needsFlush = (sb.length() > 64 * 1024);
8235        }
8236
8237        // Flush immediately if the buffer's grown too large, or this
8238        // is a non-system app.  Non-system apps are isolated with a
8239        // different tag & policy and not batched.
8240        //
8241        // Batching is useful during internal testing with
8242        // StrictMode settings turned up high.  Without batching,
8243        // thousands of separate files could be created on boot.
8244        if (!isSystemApp || needsFlush) {
8245            new Thread("Error dump: " + dropboxTag) {
8246                @Override
8247                public void run() {
8248                    String report;
8249                    synchronized (sb) {
8250                        report = sb.toString();
8251                        sb.delete(0, sb.length());
8252                        sb.trimToSize();
8253                    }
8254                    if (report.length() != 0) {
8255                        dbox.addText(dropboxTag, report);
8256                    }
8257                }
8258            }.start();
8259            return;
8260        }
8261
8262        // System app batching:
8263        if (!bufferWasEmpty) {
8264            // An existing dropbox-writing thread is outstanding, so
8265            // we don't need to start it up.  The existing thread will
8266            // catch the buffer appends we just did.
8267            return;
8268        }
8269
8270        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8271        // (After this point, we shouldn't access AMS internal data structures.)
8272        new Thread("Error dump: " + dropboxTag) {
8273            @Override
8274            public void run() {
8275                // 5 second sleep to let stacks arrive and be batched together
8276                try {
8277                    Thread.sleep(5000);  // 5 seconds
8278                } catch (InterruptedException e) {}
8279
8280                String errorReport;
8281                synchronized (mStrictModeBuffer) {
8282                    errorReport = mStrictModeBuffer.toString();
8283                    if (errorReport.length() == 0) {
8284                        return;
8285                    }
8286                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8287                    mStrictModeBuffer.trimToSize();
8288                }
8289                dbox.addText(dropboxTag, errorReport);
8290            }
8291        }.start();
8292    }
8293
8294    /**
8295     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8296     * @param app object of the crashing app, null for the system server
8297     * @param tag reported by the caller
8298     * @param crashInfo describing the context of the error
8299     * @return true if the process should exit immediately (WTF is fatal)
8300     */
8301    public boolean handleApplicationWtf(IBinder app, String tag,
8302            ApplicationErrorReport.CrashInfo crashInfo) {
8303        ProcessRecord r = findAppProcess(app, "WTF");
8304        final String processName = app == null ? "system_server"
8305                : (r == null ? "unknown" : r.processName);
8306
8307        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8308                processName,
8309                r == null ? -1 : r.info.flags,
8310                tag, crashInfo.exceptionMessage);
8311
8312        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8313
8314        if (r != null && r.pid != Process.myPid() &&
8315                Settings.Global.getInt(mContext.getContentResolver(),
8316                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8317            crashApplication(r, crashInfo);
8318            return true;
8319        } else {
8320            return false;
8321        }
8322    }
8323
8324    /**
8325     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8326     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8327     */
8328    private ProcessRecord findAppProcess(IBinder app, String reason) {
8329        if (app == null) {
8330            return null;
8331        }
8332
8333        synchronized (this) {
8334            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8335                final int NA = apps.size();
8336                for (int ia=0; ia<NA; ia++) {
8337                    ProcessRecord p = apps.valueAt(ia);
8338                    if (p.thread != null && p.thread.asBinder() == app) {
8339                        return p;
8340                    }
8341                }
8342            }
8343
8344            Slog.w(TAG, "Can't find mystery application for " + reason
8345                    + " from pid=" + Binder.getCallingPid()
8346                    + " uid=" + Binder.getCallingUid() + ": " + app);
8347            return null;
8348        }
8349    }
8350
8351    /**
8352     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8353     * to append various headers to the dropbox log text.
8354     */
8355    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8356            StringBuilder sb) {
8357        // Watchdog thread ends up invoking this function (with
8358        // a null ProcessRecord) to add the stack file to dropbox.
8359        // Do not acquire a lock on this (am) in such cases, as it
8360        // could cause a potential deadlock, if and when watchdog
8361        // is invoked due to unavailability of lock on am and it
8362        // would prevent watchdog from killing system_server.
8363        if (process == null) {
8364            sb.append("Process: ").append(processName).append("\n");
8365            return;
8366        }
8367        // Note: ProcessRecord 'process' is guarded by the service
8368        // instance.  (notably process.pkgList, which could otherwise change
8369        // concurrently during execution of this method)
8370        synchronized (this) {
8371            sb.append("Process: ").append(processName).append("\n");
8372            int flags = process.info.flags;
8373            IPackageManager pm = AppGlobals.getPackageManager();
8374            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8375            for (String pkg : process.pkgList) {
8376                sb.append("Package: ").append(pkg);
8377                try {
8378                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8379                    if (pi != null) {
8380                        sb.append(" v").append(pi.versionCode);
8381                        if (pi.versionName != null) {
8382                            sb.append(" (").append(pi.versionName).append(")");
8383                        }
8384                    }
8385                } catch (RemoteException e) {
8386                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8387                }
8388                sb.append("\n");
8389            }
8390        }
8391    }
8392
8393    private static String processClass(ProcessRecord process) {
8394        if (process == null || process.pid == MY_PID) {
8395            return "system_server";
8396        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8397            return "system_app";
8398        } else {
8399            return "data_app";
8400        }
8401    }
8402
8403    /**
8404     * Write a description of an error (crash, WTF, ANR) to the drop box.
8405     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8406     * @param process which caused the error, null means the system server
8407     * @param activity which triggered the error, null if unknown
8408     * @param parent activity related to the error, null if unknown
8409     * @param subject line related to the error, null if absent
8410     * @param report in long form describing the error, null if absent
8411     * @param logFile to include in the report, null if none
8412     * @param crashInfo giving an application stack trace, null if absent
8413     */
8414    public void addErrorToDropBox(String eventType,
8415            ProcessRecord process, String processName, ActivityRecord activity,
8416            ActivityRecord parent, String subject,
8417            final String report, final File logFile,
8418            final ApplicationErrorReport.CrashInfo crashInfo) {
8419        // NOTE -- this must never acquire the ActivityManagerService lock,
8420        // otherwise the watchdog may be prevented from resetting the system.
8421
8422        final String dropboxTag = processClass(process) + "_" + eventType;
8423        final DropBoxManager dbox = (DropBoxManager)
8424                mContext.getSystemService(Context.DROPBOX_SERVICE);
8425
8426        // Exit early if the dropbox isn't configured to accept this report type.
8427        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8428
8429        final StringBuilder sb = new StringBuilder(1024);
8430        appendDropBoxProcessHeaders(process, processName, sb);
8431        if (activity != null) {
8432            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8433        }
8434        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8435            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8436        }
8437        if (parent != null && parent != activity) {
8438            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8439        }
8440        if (subject != null) {
8441            sb.append("Subject: ").append(subject).append("\n");
8442        }
8443        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8444        if (Debug.isDebuggerConnected()) {
8445            sb.append("Debugger: Connected\n");
8446        }
8447        sb.append("\n");
8448
8449        // Do the rest in a worker thread to avoid blocking the caller on I/O
8450        // (After this point, we shouldn't access AMS internal data structures.)
8451        Thread worker = new Thread("Error dump: " + dropboxTag) {
8452            @Override
8453            public void run() {
8454                if (report != null) {
8455                    sb.append(report);
8456                }
8457                if (logFile != null) {
8458                    try {
8459                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8460                    } catch (IOException e) {
8461                        Slog.e(TAG, "Error reading " + logFile, e);
8462                    }
8463                }
8464                if (crashInfo != null && crashInfo.stackTrace != null) {
8465                    sb.append(crashInfo.stackTrace);
8466                }
8467
8468                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8469                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8470                if (lines > 0) {
8471                    sb.append("\n");
8472
8473                    // Merge several logcat streams, and take the last N lines
8474                    InputStreamReader input = null;
8475                    try {
8476                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8477                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8478                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8479
8480                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8481                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8482                        input = new InputStreamReader(logcat.getInputStream());
8483
8484                        int num;
8485                        char[] buf = new char[8192];
8486                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8487                    } catch (IOException e) {
8488                        Slog.e(TAG, "Error running logcat", e);
8489                    } finally {
8490                        if (input != null) try { input.close(); } catch (IOException e) {}
8491                    }
8492                }
8493
8494                dbox.addText(dropboxTag, sb.toString());
8495            }
8496        };
8497
8498        if (process == null) {
8499            // If process is null, we are being called from some internal code
8500            // and may be about to die -- run this synchronously.
8501            worker.run();
8502        } else {
8503            worker.start();
8504        }
8505    }
8506
8507    /**
8508     * Bring up the "unexpected error" dialog box for a crashing app.
8509     * Deal with edge cases (intercepts from instrumented applications,
8510     * ActivityController, error intent receivers, that sort of thing).
8511     * @param r the application crashing
8512     * @param crashInfo describing the failure
8513     */
8514    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8515        long timeMillis = System.currentTimeMillis();
8516        String shortMsg = crashInfo.exceptionClassName;
8517        String longMsg = crashInfo.exceptionMessage;
8518        String stackTrace = crashInfo.stackTrace;
8519        if (shortMsg != null && longMsg != null) {
8520            longMsg = shortMsg + ": " + longMsg;
8521        } else if (shortMsg != null) {
8522            longMsg = shortMsg;
8523        }
8524
8525        AppErrorResult result = new AppErrorResult();
8526        synchronized (this) {
8527            if (mController != null) {
8528                try {
8529                    String name = r != null ? r.processName : null;
8530                    int pid = r != null ? r.pid : Binder.getCallingPid();
8531                    if (!mController.appCrashed(name, pid,
8532                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8533                        Slog.w(TAG, "Force-killing crashed app " + name
8534                                + " at watcher's request");
8535                        Process.killProcess(pid);
8536                        return;
8537                    }
8538                } catch (RemoteException e) {
8539                    mController = null;
8540                }
8541            }
8542
8543            final long origId = Binder.clearCallingIdentity();
8544
8545            // If this process is running instrumentation, finish it.
8546            if (r != null && r.instrumentationClass != null) {
8547                Slog.w(TAG, "Error in app " + r.processName
8548                      + " running instrumentation " + r.instrumentationClass + ":");
8549                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8550                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8551                Bundle info = new Bundle();
8552                info.putString("shortMsg", shortMsg);
8553                info.putString("longMsg", longMsg);
8554                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8555                Binder.restoreCallingIdentity(origId);
8556                return;
8557            }
8558
8559            // If we can't identify the process or it's already exceeded its crash quota,
8560            // quit right away without showing a crash dialog.
8561            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8562                Binder.restoreCallingIdentity(origId);
8563                return;
8564            }
8565
8566            Message msg = Message.obtain();
8567            msg.what = SHOW_ERROR_MSG;
8568            HashMap data = new HashMap();
8569            data.put("result", result);
8570            data.put("app", r);
8571            msg.obj = data;
8572            mHandler.sendMessage(msg);
8573
8574            Binder.restoreCallingIdentity(origId);
8575        }
8576
8577        int res = result.get();
8578
8579        Intent appErrorIntent = null;
8580        synchronized (this) {
8581            if (r != null && !r.isolated) {
8582                // XXX Can't keep track of crash time for isolated processes,
8583                // since they don't have a persistent identity.
8584                mProcessCrashTimes.put(r.info.processName, r.uid,
8585                        SystemClock.uptimeMillis());
8586            }
8587            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8588                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8589            }
8590        }
8591
8592        if (appErrorIntent != null) {
8593            try {
8594                mContext.startActivity(appErrorIntent);
8595            } catch (ActivityNotFoundException e) {
8596                Slog.w(TAG, "bug report receiver dissappeared", e);
8597            }
8598        }
8599    }
8600
8601    Intent createAppErrorIntentLocked(ProcessRecord r,
8602            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8603        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8604        if (report == null) {
8605            return null;
8606        }
8607        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8608        result.setComponent(r.errorReportReceiver);
8609        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8610        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8611        return result;
8612    }
8613
8614    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8615            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8616        if (r.errorReportReceiver == null) {
8617            return null;
8618        }
8619
8620        if (!r.crashing && !r.notResponding) {
8621            return null;
8622        }
8623
8624        ApplicationErrorReport report = new ApplicationErrorReport();
8625        report.packageName = r.info.packageName;
8626        report.installerPackageName = r.errorReportReceiver.getPackageName();
8627        report.processName = r.processName;
8628        report.time = timeMillis;
8629        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8630
8631        if (r.crashing) {
8632            report.type = ApplicationErrorReport.TYPE_CRASH;
8633            report.crashInfo = crashInfo;
8634        } else if (r.notResponding) {
8635            report.type = ApplicationErrorReport.TYPE_ANR;
8636            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8637
8638            report.anrInfo.activity = r.notRespondingReport.tag;
8639            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8640            report.anrInfo.info = r.notRespondingReport.longMsg;
8641        }
8642
8643        return report;
8644    }
8645
8646    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8647        enforceNotIsolatedCaller("getProcessesInErrorState");
8648        // assume our apps are happy - lazy create the list
8649        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8650
8651        final boolean allUsers = ActivityManager.checkUidPermission(
8652                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8653                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8654        int userId = UserHandle.getUserId(Binder.getCallingUid());
8655
8656        synchronized (this) {
8657
8658            // iterate across all processes
8659            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8660                ProcessRecord app = mLruProcesses.get(i);
8661                if (!allUsers && app.userId != userId) {
8662                    continue;
8663                }
8664                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8665                    // This one's in trouble, so we'll generate a report for it
8666                    // crashes are higher priority (in case there's a crash *and* an anr)
8667                    ActivityManager.ProcessErrorStateInfo report = null;
8668                    if (app.crashing) {
8669                        report = app.crashingReport;
8670                    } else if (app.notResponding) {
8671                        report = app.notRespondingReport;
8672                    }
8673
8674                    if (report != null) {
8675                        if (errList == null) {
8676                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8677                        }
8678                        errList.add(report);
8679                    } else {
8680                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8681                                " crashing = " + app.crashing +
8682                                " notResponding = " + app.notResponding);
8683                    }
8684                }
8685            }
8686        }
8687
8688        return errList;
8689    }
8690
8691    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8692        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8693            if (currApp != null) {
8694                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8695            }
8696            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8697        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8698            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8699        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8700            if (currApp != null) {
8701                currApp.lru = 0;
8702            }
8703            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8704        } else if (adj >= ProcessList.SERVICE_ADJ) {
8705            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8706        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8707            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8708        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8709            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8710        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8711            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8712        } else {
8713            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8714        }
8715    }
8716
8717    private void fillInProcMemInfo(ProcessRecord app,
8718            ActivityManager.RunningAppProcessInfo outInfo) {
8719        outInfo.pid = app.pid;
8720        outInfo.uid = app.info.uid;
8721        if (mHeavyWeightProcess == app) {
8722            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8723        }
8724        if (app.persistent) {
8725            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8726        }
8727        if (app.hasActivities) {
8728            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8729        }
8730        outInfo.lastTrimLevel = app.trimMemoryLevel;
8731        int adj = app.curAdj;
8732        outInfo.importance = oomAdjToImportance(adj, outInfo);
8733        outInfo.importanceReasonCode = app.adjTypeCode;
8734    }
8735
8736    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8737        enforceNotIsolatedCaller("getRunningAppProcesses");
8738        // Lazy instantiation of list
8739        List<ActivityManager.RunningAppProcessInfo> runList = null;
8740        final boolean allUsers = ActivityManager.checkUidPermission(
8741                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8742                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8743        int userId = UserHandle.getUserId(Binder.getCallingUid());
8744        synchronized (this) {
8745            // Iterate across all processes
8746            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8747                ProcessRecord app = mLruProcesses.get(i);
8748                if (!allUsers && app.userId != userId) {
8749                    continue;
8750                }
8751                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8752                    // Generate process state info for running application
8753                    ActivityManager.RunningAppProcessInfo currApp =
8754                        new ActivityManager.RunningAppProcessInfo(app.processName,
8755                                app.pid, app.getPackageList());
8756                    fillInProcMemInfo(app, currApp);
8757                    if (app.adjSource instanceof ProcessRecord) {
8758                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8759                        currApp.importanceReasonImportance = oomAdjToImportance(
8760                                app.adjSourceOom, null);
8761                    } else if (app.adjSource instanceof ActivityRecord) {
8762                        ActivityRecord r = (ActivityRecord)app.adjSource;
8763                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8764                    }
8765                    if (app.adjTarget instanceof ComponentName) {
8766                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8767                    }
8768                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8769                    //        + " lru=" + currApp.lru);
8770                    if (runList == null) {
8771                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8772                    }
8773                    runList.add(currApp);
8774                }
8775            }
8776        }
8777        return runList;
8778    }
8779
8780    public List<ApplicationInfo> getRunningExternalApplications() {
8781        enforceNotIsolatedCaller("getRunningExternalApplications");
8782        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8783        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8784        if (runningApps != null && runningApps.size() > 0) {
8785            Set<String> extList = new HashSet<String>();
8786            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8787                if (app.pkgList != null) {
8788                    for (String pkg : app.pkgList) {
8789                        extList.add(pkg);
8790                    }
8791                }
8792            }
8793            IPackageManager pm = AppGlobals.getPackageManager();
8794            for (String pkg : extList) {
8795                try {
8796                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8797                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8798                        retList.add(info);
8799                    }
8800                } catch (RemoteException e) {
8801                }
8802            }
8803        }
8804        return retList;
8805    }
8806
8807    @Override
8808    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8809        enforceNotIsolatedCaller("getMyMemoryState");
8810        synchronized (this) {
8811            ProcessRecord proc;
8812            synchronized (mPidsSelfLocked) {
8813                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8814            }
8815            fillInProcMemInfo(proc, outInfo);
8816        }
8817    }
8818
8819    @Override
8820    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8821        if (checkCallingPermission(android.Manifest.permission.DUMP)
8822                != PackageManager.PERMISSION_GRANTED) {
8823            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8824                    + Binder.getCallingPid()
8825                    + ", uid=" + Binder.getCallingUid()
8826                    + " without permission "
8827                    + android.Manifest.permission.DUMP);
8828            return;
8829        }
8830
8831        boolean dumpAll = false;
8832        boolean dumpClient = false;
8833        String dumpPackage = null;
8834
8835        int opti = 0;
8836        while (opti < args.length) {
8837            String opt = args[opti];
8838            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8839                break;
8840            }
8841            opti++;
8842            if ("-a".equals(opt)) {
8843                dumpAll = true;
8844            } else if ("-c".equals(opt)) {
8845                dumpClient = true;
8846            } else if ("-h".equals(opt)) {
8847                pw.println("Activity manager dump options:");
8848                pw.println("  [-a] [-c] [-h] [cmd] ...");
8849                pw.println("  cmd may be one of:");
8850                pw.println("    a[ctivities]: activity stack state");
8851                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8852                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8853                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8854                pw.println("    o[om]: out of memory management");
8855                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8856                pw.println("    provider [COMP_SPEC]: provider client-side state");
8857                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8858                pw.println("    service [COMP_SPEC]: service client-side state");
8859                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8860                pw.println("    all: dump all activities");
8861                pw.println("    top: dump the top activity");
8862                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8863                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8864                pw.println("    a partial substring in a component name, a");
8865                pw.println("    hex object identifier.");
8866                pw.println("  -a: include all available server state.");
8867                pw.println("  -c: include client state.");
8868                return;
8869            } else {
8870                pw.println("Unknown argument: " + opt + "; use -h for help");
8871            }
8872        }
8873
8874        long origId = Binder.clearCallingIdentity();
8875        boolean more = false;
8876        // Is the caller requesting to dump a particular piece of data?
8877        if (opti < args.length) {
8878            String cmd = args[opti];
8879            opti++;
8880            if ("activities".equals(cmd) || "a".equals(cmd)) {
8881                synchronized (this) {
8882                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8883                }
8884            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8885                String[] newArgs;
8886                String name;
8887                if (opti >= args.length) {
8888                    name = null;
8889                    newArgs = EMPTY_STRING_ARRAY;
8890                } else {
8891                    name = args[opti];
8892                    opti++;
8893                    newArgs = new String[args.length - opti];
8894                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8895                            args.length - opti);
8896                }
8897                synchronized (this) {
8898                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8899                }
8900            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8901                String[] newArgs;
8902                String name;
8903                if (opti >= args.length) {
8904                    name = null;
8905                    newArgs = EMPTY_STRING_ARRAY;
8906                } else {
8907                    name = args[opti];
8908                    opti++;
8909                    newArgs = new String[args.length - opti];
8910                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8911                            args.length - opti);
8912                }
8913                synchronized (this) {
8914                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8915                }
8916            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8917                String[] newArgs;
8918                String name;
8919                if (opti >= args.length) {
8920                    name = null;
8921                    newArgs = EMPTY_STRING_ARRAY;
8922                } else {
8923                    name = args[opti];
8924                    opti++;
8925                    newArgs = new String[args.length - opti];
8926                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8927                            args.length - opti);
8928                }
8929                synchronized (this) {
8930                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8931                }
8932            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8933                synchronized (this) {
8934                    dumpOomLocked(fd, pw, args, opti, true);
8935                }
8936            } else if ("provider".equals(cmd)) {
8937                String[] newArgs;
8938                String name;
8939                if (opti >= args.length) {
8940                    name = null;
8941                    newArgs = EMPTY_STRING_ARRAY;
8942                } else {
8943                    name = args[opti];
8944                    opti++;
8945                    newArgs = new String[args.length - opti];
8946                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8947                }
8948                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8949                    pw.println("No providers match: " + name);
8950                    pw.println("Use -h for help.");
8951                }
8952            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8953                synchronized (this) {
8954                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8955                }
8956            } else if ("service".equals(cmd)) {
8957                String[] newArgs;
8958                String name;
8959                if (opti >= args.length) {
8960                    name = null;
8961                    newArgs = EMPTY_STRING_ARRAY;
8962                } else {
8963                    name = args[opti];
8964                    opti++;
8965                    newArgs = new String[args.length - opti];
8966                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8967                            args.length - opti);
8968                }
8969                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8970                    pw.println("No services match: " + name);
8971                    pw.println("Use -h for help.");
8972                }
8973            } else if ("package".equals(cmd)) {
8974                String[] newArgs;
8975                if (opti >= args.length) {
8976                    pw.println("package: no package name specified");
8977                    pw.println("Use -h for help.");
8978                } else {
8979                    dumpPackage = args[opti];
8980                    opti++;
8981                    newArgs = new String[args.length - opti];
8982                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8983                            args.length - opti);
8984                    args = newArgs;
8985                    opti = 0;
8986                    more = true;
8987                }
8988            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8989                synchronized (this) {
8990                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8991                }
8992            } else {
8993                // Dumping a single activity?
8994                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8995                    pw.println("Bad activity command, or no activities match: " + cmd);
8996                    pw.println("Use -h for help.");
8997                }
8998            }
8999            if (!more) {
9000                Binder.restoreCallingIdentity(origId);
9001                return;
9002            }
9003        }
9004
9005        // No piece of data specified, dump everything.
9006        synchronized (this) {
9007            boolean needSep;
9008            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9009            if (needSep) {
9010                pw.println(" ");
9011            }
9012            if (dumpAll) {
9013                pw.println("-------------------------------------------------------------------------------");
9014            }
9015            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9016            if (needSep) {
9017                pw.println(" ");
9018            }
9019            if (dumpAll) {
9020                pw.println("-------------------------------------------------------------------------------");
9021            }
9022            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9023            if (needSep) {
9024                pw.println(" ");
9025            }
9026            if (dumpAll) {
9027                pw.println("-------------------------------------------------------------------------------");
9028            }
9029            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9030            if (needSep) {
9031                pw.println(" ");
9032            }
9033            if (dumpAll) {
9034                pw.println("-------------------------------------------------------------------------------");
9035            }
9036            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9037            if (needSep) {
9038                pw.println(" ");
9039            }
9040            if (dumpAll) {
9041                pw.println("-------------------------------------------------------------------------------");
9042            }
9043            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9044        }
9045        Binder.restoreCallingIdentity(origId);
9046    }
9047
9048    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9049            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9050        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9051        pw.println("  Main stack:");
9052        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9053                dumpPackage);
9054        pw.println(" ");
9055        pw.println("  Running activities (most recent first):");
9056        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9057                dumpPackage);
9058        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9059            pw.println(" ");
9060            pw.println("  Activities waiting for another to become visible:");
9061            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9062                    !dumpAll, false, dumpPackage);
9063        }
9064        if (mMainStack.mStoppingActivities.size() > 0) {
9065            pw.println(" ");
9066            pw.println("  Activities waiting to stop:");
9067            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9068                    !dumpAll, false, dumpPackage);
9069        }
9070        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9071            pw.println(" ");
9072            pw.println("  Activities waiting to sleep:");
9073            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9074                    !dumpAll, false, dumpPackage);
9075        }
9076        if (mMainStack.mFinishingActivities.size() > 0) {
9077            pw.println(" ");
9078            pw.println("  Activities waiting to finish:");
9079            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9080                    !dumpAll, false, dumpPackage);
9081        }
9082
9083        pw.println(" ");
9084        if (mMainStack.mPausingActivity != null) {
9085            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9086        }
9087        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9088        pw.println("  mFocusedActivity: " + mFocusedActivity);
9089        if (dumpAll) {
9090            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9091            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9092            pw.println("  mDismissKeyguardOnNextActivity: "
9093                    + mMainStack.mDismissKeyguardOnNextActivity);
9094        }
9095
9096        if (mRecentTasks.size() > 0) {
9097            pw.println();
9098            pw.println("  Recent tasks:");
9099
9100            final int N = mRecentTasks.size();
9101            for (int i=0; i<N; i++) {
9102                TaskRecord tr = mRecentTasks.get(i);
9103                if (dumpPackage != null) {
9104                    if (tr.realActivity == null ||
9105                            !dumpPackage.equals(tr.realActivity)) {
9106                        continue;
9107                    }
9108                }
9109                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9110                        pw.println(tr);
9111                if (dumpAll) {
9112                    mRecentTasks.get(i).dump(pw, "    ");
9113                }
9114            }
9115        }
9116
9117        if (dumpAll) {
9118            pw.println(" ");
9119            pw.println("  mCurTask: " + mCurTask);
9120        }
9121
9122        return true;
9123    }
9124
9125    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9126            int opti, boolean dumpAll, String dumpPackage) {
9127        boolean needSep = false;
9128        int numPers = 0;
9129
9130        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9131
9132        if (dumpAll) {
9133            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9134                final int NA = procs.size();
9135                for (int ia=0; ia<NA; ia++) {
9136                    ProcessRecord r = procs.valueAt(ia);
9137                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9138                        continue;
9139                    }
9140                    if (!needSep) {
9141                        pw.println("  All known processes:");
9142                        needSep = true;
9143                    }
9144                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9145                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9146                        pw.print(" "); pw.println(r);
9147                    r.dump(pw, "    ");
9148                    if (r.persistent) {
9149                        numPers++;
9150                    }
9151                }
9152            }
9153        }
9154
9155        if (mIsolatedProcesses.size() > 0) {
9156            if (needSep) pw.println(" ");
9157            needSep = true;
9158            pw.println("  Isolated process list (sorted by uid):");
9159            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9160                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9161                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9162                    continue;
9163                }
9164                pw.println(String.format("%sIsolated #%2d: %s",
9165                        "    ", i, r.toString()));
9166            }
9167        }
9168
9169        if (mLruProcesses.size() > 0) {
9170            if (needSep) pw.println(" ");
9171            needSep = true;
9172            pw.println("  Process LRU list (sorted by oom_adj):");
9173            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9174                    "Proc", "PERS", false, dumpPackage);
9175            needSep = true;
9176        }
9177
9178        if (dumpAll) {
9179            synchronized (mPidsSelfLocked) {
9180                boolean printed = false;
9181                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9182                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9183                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9184                        continue;
9185                    }
9186                    if (!printed) {
9187                        if (needSep) pw.println(" ");
9188                        needSep = true;
9189                        pw.println("  PID mappings:");
9190                        printed = true;
9191                    }
9192                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9193                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9194                }
9195            }
9196        }
9197
9198        if (mForegroundProcesses.size() > 0) {
9199            synchronized (mPidsSelfLocked) {
9200                boolean printed = false;
9201                for (int i=0; i<mForegroundProcesses.size(); i++) {
9202                    ProcessRecord r = mPidsSelfLocked.get(
9203                            mForegroundProcesses.valueAt(i).pid);
9204                    if (dumpPackage != null && (r == null
9205                            || !dumpPackage.equals(r.info.packageName))) {
9206                        continue;
9207                    }
9208                    if (!printed) {
9209                        if (needSep) pw.println(" ");
9210                        needSep = true;
9211                        pw.println("  Foreground Processes:");
9212                        printed = true;
9213                    }
9214                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9215                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9216                }
9217            }
9218        }
9219
9220        if (mPersistentStartingProcesses.size() > 0) {
9221            if (needSep) pw.println(" ");
9222            needSep = true;
9223            pw.println("  Persisent processes that are starting:");
9224            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9225                    "Starting Norm", "Restarting PERS", dumpPackage);
9226        }
9227
9228        if (mRemovedProcesses.size() > 0) {
9229            if (needSep) pw.println(" ");
9230            needSep = true;
9231            pw.println("  Processes that are being removed:");
9232            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9233                    "Removed Norm", "Removed PERS", dumpPackage);
9234        }
9235
9236        if (mProcessesOnHold.size() > 0) {
9237            if (needSep) pw.println(" ");
9238            needSep = true;
9239            pw.println("  Processes that are on old until the system is ready:");
9240            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9241                    "OnHold Norm", "OnHold PERS", dumpPackage);
9242        }
9243
9244        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9245
9246        if (mProcessCrashTimes.getMap().size() > 0) {
9247            boolean printed = false;
9248            long now = SystemClock.uptimeMillis();
9249            for (Map.Entry<String, SparseArray<Long>> procs
9250                    : mProcessCrashTimes.getMap().entrySet()) {
9251                String pname = procs.getKey();
9252                SparseArray<Long> uids = procs.getValue();
9253                final int N = uids.size();
9254                for (int i=0; i<N; i++) {
9255                    int puid = uids.keyAt(i);
9256                    ProcessRecord r = mProcessNames.get(pname, puid);
9257                    if (dumpPackage != null && (r == null
9258                            || !dumpPackage.equals(r.info.packageName))) {
9259                        continue;
9260                    }
9261                    if (!printed) {
9262                        if (needSep) pw.println(" ");
9263                        needSep = true;
9264                        pw.println("  Time since processes crashed:");
9265                        printed = true;
9266                    }
9267                    pw.print("    Process "); pw.print(pname);
9268                            pw.print(" uid "); pw.print(puid);
9269                            pw.print(": last crashed ");
9270                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9271                            pw.println(" ago");
9272                }
9273            }
9274        }
9275
9276        if (mBadProcesses.getMap().size() > 0) {
9277            boolean printed = false;
9278            for (Map.Entry<String, SparseArray<Long>> procs
9279                    : mBadProcesses.getMap().entrySet()) {
9280                String pname = procs.getKey();
9281                SparseArray<Long> uids = procs.getValue();
9282                final int N = uids.size();
9283                for (int i=0; i<N; i++) {
9284                    int puid = uids.keyAt(i);
9285                    ProcessRecord r = mProcessNames.get(pname, puid);
9286                    if (dumpPackage != null && (r == null
9287                            || !dumpPackage.equals(r.info.packageName))) {
9288                        continue;
9289                    }
9290                    if (!printed) {
9291                        if (needSep) pw.println(" ");
9292                        needSep = true;
9293                        pw.println("  Bad processes:");
9294                    }
9295                    pw.print("    Bad process "); pw.print(pname);
9296                            pw.print(" uid "); pw.print(puid);
9297                            pw.print(": crashed at time ");
9298                            pw.println(uids.valueAt(i));
9299                }
9300            }
9301        }
9302
9303        pw.println();
9304        pw.println("  mStartedUsers:");
9305        for (int i=0; i<mStartedUsers.size(); i++) {
9306            UserStartedState uss = mStartedUsers.valueAt(i);
9307            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9308                    pw.print(": "); uss.dump("", pw);
9309        }
9310        pw.print("  mUserLru: [");
9311        for (int i=0; i<mUserLru.size(); i++) {
9312            if (i > 0) pw.print(", ");
9313            pw.print(mUserLru.get(i));
9314        }
9315        pw.println("]");
9316        if (dumpAll) {
9317            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9318        }
9319        pw.println("  mHomeProcess: " + mHomeProcess);
9320        pw.println("  mPreviousProcess: " + mPreviousProcess);
9321        if (dumpAll) {
9322            StringBuilder sb = new StringBuilder(128);
9323            sb.append("  mPreviousProcessVisibleTime: ");
9324            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9325            pw.println(sb);
9326        }
9327        if (mHeavyWeightProcess != null) {
9328            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9329        }
9330        pw.println("  mConfiguration: " + mConfiguration);
9331        if (dumpAll) {
9332            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9333            if (mCompatModePackages.getPackages().size() > 0) {
9334                boolean printed = false;
9335                for (Map.Entry<String, Integer> entry
9336                        : mCompatModePackages.getPackages().entrySet()) {
9337                    String pkg = entry.getKey();
9338                    int mode = entry.getValue();
9339                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9340                        continue;
9341                    }
9342                    if (!printed) {
9343                        pw.println("  mScreenCompatPackages:");
9344                        printed = true;
9345                    }
9346                    pw.print("    "); pw.print(pkg); pw.print(": ");
9347                            pw.print(mode); pw.println();
9348                }
9349            }
9350        }
9351        if (mSleeping || mWentToSleep || mLockScreenShown) {
9352            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9353                    + " mLockScreenShown " + mLockScreenShown);
9354        }
9355        if (mShuttingDown) {
9356            pw.println("  mShuttingDown=" + mShuttingDown);
9357        }
9358        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9359                || mOrigWaitForDebugger) {
9360            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9361                    + " mDebugTransient=" + mDebugTransient
9362                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9363        }
9364        if (mOpenGlTraceApp != null) {
9365            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9366        }
9367        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9368                || mProfileFd != null) {
9369            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9370            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9371            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9372                    + mAutoStopProfiler);
9373        }
9374        if (mAlwaysFinishActivities || mController != null) {
9375            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9376                    + " mController=" + mController);
9377        }
9378        if (dumpAll) {
9379            pw.println("  Total persistent processes: " + numPers);
9380            pw.println("  mStartRunning=" + mStartRunning
9381                    + " mProcessesReady=" + mProcessesReady
9382                    + " mSystemReady=" + mSystemReady);
9383            pw.println("  mBooting=" + mBooting
9384                    + " mBooted=" + mBooted
9385                    + " mFactoryTest=" + mFactoryTest);
9386            pw.print("  mLastPowerCheckRealtime=");
9387                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9388                    pw.println("");
9389            pw.print("  mLastPowerCheckUptime=");
9390                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9391                    pw.println("");
9392            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9393            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9394            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9395            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9396                    + " mNumHiddenProcs=" + mNumHiddenProcs
9397                    + " mNumServiceProcs=" + mNumServiceProcs
9398                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9399        }
9400
9401        return true;
9402    }
9403
9404    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9405            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9406        if (mProcessesToGc.size() > 0) {
9407            boolean printed = false;
9408            long now = SystemClock.uptimeMillis();
9409            for (int i=0; i<mProcessesToGc.size(); i++) {
9410                ProcessRecord proc = mProcessesToGc.get(i);
9411                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9412                    continue;
9413                }
9414                if (!printed) {
9415                    if (needSep) pw.println(" ");
9416                    needSep = true;
9417                    pw.println("  Processes that are waiting to GC:");
9418                    printed = true;
9419                }
9420                pw.print("    Process "); pw.println(proc);
9421                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9422                        pw.print(", last gced=");
9423                        pw.print(now-proc.lastRequestedGc);
9424                        pw.print(" ms ago, last lowMem=");
9425                        pw.print(now-proc.lastLowMemory);
9426                        pw.println(" ms ago");
9427
9428            }
9429        }
9430        return needSep;
9431    }
9432
9433    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9434            int opti, boolean dumpAll) {
9435        boolean needSep = false;
9436
9437        if (mLruProcesses.size() > 0) {
9438            if (needSep) pw.println(" ");
9439            needSep = true;
9440            pw.println("  OOM levels:");
9441            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9442            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9443            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9444            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9445            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9446            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9447            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9448            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9449            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9450            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9451            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9452            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9453            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9454
9455            if (needSep) pw.println(" ");
9456            needSep = true;
9457            pw.println("  Process OOM control:");
9458            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9459                    "Proc", "PERS", true, null);
9460            needSep = true;
9461        }
9462
9463        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9464
9465        pw.println();
9466        pw.println("  mHomeProcess: " + mHomeProcess);
9467        pw.println("  mPreviousProcess: " + mPreviousProcess);
9468        if (mHeavyWeightProcess != null) {
9469            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9470        }
9471
9472        return true;
9473    }
9474
9475    /**
9476     * There are three ways to call this:
9477     *  - no provider specified: dump all the providers
9478     *  - a flattened component name that matched an existing provider was specified as the
9479     *    first arg: dump that one provider
9480     *  - the first arg isn't the flattened component name of an existing provider:
9481     *    dump all providers whose component contains the first arg as a substring
9482     */
9483    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9484            int opti, boolean dumpAll) {
9485        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9486    }
9487
9488    static class ItemMatcher {
9489        ArrayList<ComponentName> components;
9490        ArrayList<String> strings;
9491        ArrayList<Integer> objects;
9492        boolean all;
9493
9494        ItemMatcher() {
9495            all = true;
9496        }
9497
9498        void build(String name) {
9499            ComponentName componentName = ComponentName.unflattenFromString(name);
9500            if (componentName != null) {
9501                if (components == null) {
9502                    components = new ArrayList<ComponentName>();
9503                }
9504                components.add(componentName);
9505                all = false;
9506            } else {
9507                int objectId = 0;
9508                // Not a '/' separated full component name; maybe an object ID?
9509                try {
9510                    objectId = Integer.parseInt(name, 16);
9511                    if (objects == null) {
9512                        objects = new ArrayList<Integer>();
9513                    }
9514                    objects.add(objectId);
9515                    all = false;
9516                } catch (RuntimeException e) {
9517                    // Not an integer; just do string match.
9518                    if (strings == null) {
9519                        strings = new ArrayList<String>();
9520                    }
9521                    strings.add(name);
9522                    all = false;
9523                }
9524            }
9525        }
9526
9527        int build(String[] args, int opti) {
9528            for (; opti<args.length; opti++) {
9529                String name = args[opti];
9530                if ("--".equals(name)) {
9531                    return opti+1;
9532                }
9533                build(name);
9534            }
9535            return opti;
9536        }
9537
9538        boolean match(Object object, ComponentName comp) {
9539            if (all) {
9540                return true;
9541            }
9542            if (components != null) {
9543                for (int i=0; i<components.size(); i++) {
9544                    if (components.get(i).equals(comp)) {
9545                        return true;
9546                    }
9547                }
9548            }
9549            if (objects != null) {
9550                for (int i=0; i<objects.size(); i++) {
9551                    if (System.identityHashCode(object) == objects.get(i)) {
9552                        return true;
9553                    }
9554                }
9555            }
9556            if (strings != null) {
9557                String flat = comp.flattenToString();
9558                for (int i=0; i<strings.size(); i++) {
9559                    if (flat.contains(strings.get(i))) {
9560                        return true;
9561                    }
9562                }
9563            }
9564            return false;
9565        }
9566    }
9567
9568    /**
9569     * There are three things that cmd can be:
9570     *  - a flattened component name that matches an existing activity
9571     *  - the cmd arg isn't the flattened component name of an existing activity:
9572     *    dump all activity whose component contains the cmd as a substring
9573     *  - A hex number of the ActivityRecord object instance.
9574     */
9575    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9576            int opti, boolean dumpAll) {
9577        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9578
9579        if ("all".equals(name)) {
9580            synchronized (this) {
9581                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9582                    activities.add(r1);
9583                }
9584            }
9585        } else if ("top".equals(name)) {
9586            synchronized (this) {
9587                final int N = mMainStack.mHistory.size();
9588                if (N > 0) {
9589                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9590                }
9591            }
9592        } else {
9593            ItemMatcher matcher = new ItemMatcher();
9594            matcher.build(name);
9595
9596            synchronized (this) {
9597                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9598                    if (matcher.match(r1, r1.intent.getComponent())) {
9599                        activities.add(r1);
9600                    }
9601                }
9602            }
9603        }
9604
9605        if (activities.size() <= 0) {
9606            return false;
9607        }
9608
9609        String[] newArgs = new String[args.length - opti];
9610        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9611
9612        TaskRecord lastTask = null;
9613        boolean needSep = false;
9614        for (int i=activities.size()-1; i>=0; i--) {
9615            ActivityRecord r = (ActivityRecord)activities.get(i);
9616            if (needSep) {
9617                pw.println();
9618            }
9619            needSep = true;
9620            synchronized (this) {
9621                if (lastTask != r.task) {
9622                    lastTask = r.task;
9623                    pw.print("TASK "); pw.print(lastTask.affinity);
9624                            pw.print(" id="); pw.println(lastTask.taskId);
9625                    if (dumpAll) {
9626                        lastTask.dump(pw, "  ");
9627                    }
9628                }
9629            }
9630            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9631        }
9632        return true;
9633    }
9634
9635    /**
9636     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9637     * there is a thread associated with the activity.
9638     */
9639    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9640            final ActivityRecord r, String[] args, boolean dumpAll) {
9641        String innerPrefix = prefix + "  ";
9642        synchronized (this) {
9643            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9644                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9645                    pw.print(" pid=");
9646                    if (r.app != null) pw.println(r.app.pid);
9647                    else pw.println("(not running)");
9648            if (dumpAll) {
9649                r.dump(pw, innerPrefix);
9650            }
9651        }
9652        if (r.app != null && r.app.thread != null) {
9653            // flush anything that is already in the PrintWriter since the thread is going
9654            // to write to the file descriptor directly
9655            pw.flush();
9656            try {
9657                TransferPipe tp = new TransferPipe();
9658                try {
9659                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9660                            r.appToken, innerPrefix, args);
9661                    tp.go(fd);
9662                } finally {
9663                    tp.kill();
9664                }
9665            } catch (IOException e) {
9666                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9667            } catch (RemoteException e) {
9668                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9669            }
9670        }
9671    }
9672
9673    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9674            int opti, boolean dumpAll, String dumpPackage) {
9675        boolean needSep = false;
9676        boolean onlyHistory = false;
9677
9678        if ("history".equals(dumpPackage)) {
9679            onlyHistory = true;
9680            dumpPackage = null;
9681        }
9682
9683        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9684        if (!onlyHistory && dumpAll) {
9685            if (mRegisteredReceivers.size() > 0) {
9686                boolean printed = false;
9687                Iterator it = mRegisteredReceivers.values().iterator();
9688                while (it.hasNext()) {
9689                    ReceiverList r = (ReceiverList)it.next();
9690                    if (dumpPackage != null && (r.app == null ||
9691                            !dumpPackage.equals(r.app.info.packageName))) {
9692                        continue;
9693                    }
9694                    if (!printed) {
9695                        pw.println("  Registered Receivers:");
9696                        needSep = true;
9697                        printed = true;
9698                    }
9699                    pw.print("  * "); pw.println(r);
9700                    r.dump(pw, "    ");
9701                }
9702            }
9703
9704            if (mReceiverResolver.dump(pw, needSep ?
9705                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9706                    "    ", dumpPackage, false)) {
9707                needSep = true;
9708            }
9709        }
9710
9711        for (BroadcastQueue q : mBroadcastQueues) {
9712            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9713        }
9714
9715        needSep = true;
9716
9717        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9718            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9719                if (needSep) {
9720                    pw.println();
9721                }
9722                needSep = true;
9723                pw.print("  Sticky broadcasts for user ");
9724                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9725                StringBuilder sb = new StringBuilder(128);
9726                for (Map.Entry<String, ArrayList<Intent>> ent
9727                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9728                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9729                    if (dumpAll) {
9730                        pw.println(":");
9731                        ArrayList<Intent> intents = ent.getValue();
9732                        final int N = intents.size();
9733                        for (int i=0; i<N; i++) {
9734                            sb.setLength(0);
9735                            sb.append("    Intent: ");
9736                            intents.get(i).toShortString(sb, false, true, false, false);
9737                            pw.println(sb.toString());
9738                            Bundle bundle = intents.get(i).getExtras();
9739                            if (bundle != null) {
9740                                pw.print("      ");
9741                                pw.println(bundle.toString());
9742                            }
9743                        }
9744                    } else {
9745                        pw.println("");
9746                    }
9747                }
9748            }
9749        }
9750
9751        if (!onlyHistory && dumpAll) {
9752            pw.println();
9753            for (BroadcastQueue queue : mBroadcastQueues) {
9754                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9755                        + queue.mBroadcastsScheduled);
9756            }
9757            pw.println("  mHandler:");
9758            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9759            needSep = true;
9760        }
9761
9762        return needSep;
9763    }
9764
9765    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9766            int opti, boolean dumpAll, String dumpPackage) {
9767        boolean needSep = true;
9768
9769        ItemMatcher matcher = new ItemMatcher();
9770        matcher.build(args, opti);
9771
9772        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9773
9774        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9775
9776        if (mLaunchingProviders.size() > 0) {
9777            boolean printed = false;
9778            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9779                ContentProviderRecord r = mLaunchingProviders.get(i);
9780                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9781                    continue;
9782                }
9783                if (!printed) {
9784                    if (needSep) pw.println(" ");
9785                    needSep = true;
9786                    pw.println("  Launching content providers:");
9787                    printed = true;
9788                }
9789                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9790                        pw.println(r);
9791            }
9792        }
9793
9794        if (mGrantedUriPermissions.size() > 0) {
9795            if (needSep) pw.println();
9796            needSep = true;
9797            pw.println("Granted Uri Permissions:");
9798            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9799                int uid = mGrantedUriPermissions.keyAt(i);
9800                HashMap<Uri, UriPermission> perms
9801                        = mGrantedUriPermissions.valueAt(i);
9802                pw.print("  * UID "); pw.print(uid);
9803                        pw.println(" holds:");
9804                for (UriPermission perm : perms.values()) {
9805                    pw.print("    "); pw.println(perm);
9806                    if (dumpAll) {
9807                        perm.dump(pw, "      ");
9808                    }
9809                }
9810            }
9811            needSep = true;
9812        }
9813
9814        return needSep;
9815    }
9816
9817    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9818            int opti, boolean dumpAll, String dumpPackage) {
9819        boolean needSep = false;
9820
9821        if (mIntentSenderRecords.size() > 0) {
9822            boolean printed = false;
9823            Iterator<WeakReference<PendingIntentRecord>> it
9824                    = mIntentSenderRecords.values().iterator();
9825            while (it.hasNext()) {
9826                WeakReference<PendingIntentRecord> ref = it.next();
9827                PendingIntentRecord rec = ref != null ? ref.get(): null;
9828                if (dumpPackage != null && (rec == null
9829                        || !dumpPackage.equals(rec.key.packageName))) {
9830                    continue;
9831                }
9832                if (!printed) {
9833                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9834                    printed = true;
9835                }
9836                needSep = true;
9837                if (rec != null) {
9838                    pw.print("  * "); pw.println(rec);
9839                    if (dumpAll) {
9840                        rec.dump(pw, "    ");
9841                    }
9842                } else {
9843                    pw.print("  * "); pw.println(ref);
9844                }
9845            }
9846        }
9847
9848        return needSep;
9849    }
9850
9851    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9852            String prefix, String label, boolean complete, boolean brief, boolean client,
9853            String dumpPackage) {
9854        TaskRecord lastTask = null;
9855        boolean needNL = false;
9856        final String innerPrefix = prefix + "      ";
9857        final String[] args = new String[0];
9858        for (int i=list.size()-1; i>=0; i--) {
9859            final ActivityRecord r = (ActivityRecord)list.get(i);
9860            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9861                continue;
9862            }
9863            final boolean full = !brief && (complete || !r.isInHistory());
9864            if (needNL) {
9865                pw.println(" ");
9866                needNL = false;
9867            }
9868            if (lastTask != r.task) {
9869                lastTask = r.task;
9870                pw.print(prefix);
9871                pw.print(full ? "* " : "  ");
9872                pw.println(lastTask);
9873                if (full) {
9874                    lastTask.dump(pw, prefix + "  ");
9875                } else if (complete) {
9876                    // Complete + brief == give a summary.  Isn't that obvious?!?
9877                    if (lastTask.intent != null) {
9878                        pw.print(prefix); pw.print("  ");
9879                                pw.println(lastTask.intent.toInsecureStringWithClip());
9880                    }
9881                }
9882            }
9883            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9884            pw.print(" #"); pw.print(i); pw.print(": ");
9885            pw.println(r);
9886            if (full) {
9887                r.dump(pw, innerPrefix);
9888            } else if (complete) {
9889                // Complete + brief == give a summary.  Isn't that obvious?!?
9890                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9891                if (r.app != null) {
9892                    pw.print(innerPrefix); pw.println(r.app);
9893                }
9894            }
9895            if (client && r.app != null && r.app.thread != null) {
9896                // flush anything that is already in the PrintWriter since the thread is going
9897                // to write to the file descriptor directly
9898                pw.flush();
9899                try {
9900                    TransferPipe tp = new TransferPipe();
9901                    try {
9902                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9903                                r.appToken, innerPrefix, args);
9904                        // Short timeout, since blocking here can
9905                        // deadlock with the application.
9906                        tp.go(fd, 2000);
9907                    } finally {
9908                        tp.kill();
9909                    }
9910                } catch (IOException e) {
9911                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9912                } catch (RemoteException e) {
9913                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9914                }
9915                needNL = true;
9916            }
9917        }
9918    }
9919
9920    private static String buildOomTag(String prefix, String space, int val, int base) {
9921        if (val == base) {
9922            if (space == null) return prefix;
9923            return prefix + "  ";
9924        }
9925        return prefix + "+" + Integer.toString(val-base);
9926    }
9927
9928    private static final int dumpProcessList(PrintWriter pw,
9929            ActivityManagerService service, List list,
9930            String prefix, String normalLabel, String persistentLabel,
9931            String dumpPackage) {
9932        int numPers = 0;
9933        final int N = list.size()-1;
9934        for (int i=N; i>=0; i--) {
9935            ProcessRecord r = (ProcessRecord)list.get(i);
9936            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9937                continue;
9938            }
9939            pw.println(String.format("%s%s #%2d: %s",
9940                    prefix, (r.persistent ? persistentLabel : normalLabel),
9941                    i, r.toString()));
9942            if (r.persistent) {
9943                numPers++;
9944            }
9945        }
9946        return numPers;
9947    }
9948
9949    private static final boolean dumpProcessOomList(PrintWriter pw,
9950            ActivityManagerService service, List<ProcessRecord> origList,
9951            String prefix, String normalLabel, String persistentLabel,
9952            boolean inclDetails, String dumpPackage) {
9953
9954        ArrayList<Pair<ProcessRecord, Integer>> list
9955                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9956        for (int i=0; i<origList.size(); i++) {
9957            ProcessRecord r = origList.get(i);
9958            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9959                continue;
9960            }
9961            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9962        }
9963
9964        if (list.size() <= 0) {
9965            return false;
9966        }
9967
9968        Comparator<Pair<ProcessRecord, Integer>> comparator
9969                = new Comparator<Pair<ProcessRecord, Integer>>() {
9970            @Override
9971            public int compare(Pair<ProcessRecord, Integer> object1,
9972                    Pair<ProcessRecord, Integer> object2) {
9973                if (object1.first.setAdj != object2.first.setAdj) {
9974                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9975                }
9976                if (object1.second.intValue() != object2.second.intValue()) {
9977                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9978                }
9979                return 0;
9980            }
9981        };
9982
9983        Collections.sort(list, comparator);
9984
9985        final long curRealtime = SystemClock.elapsedRealtime();
9986        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9987        final long curUptime = SystemClock.uptimeMillis();
9988        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9989
9990        for (int i=list.size()-1; i>=0; i--) {
9991            ProcessRecord r = list.get(i).first;
9992            String oomAdj;
9993            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9994                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9995            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9996                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9997            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9998                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9999            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10000                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10001            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10002                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10003            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10004                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10005            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10006                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10007            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10008                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10009            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10010                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10011            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10012                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10013            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10014                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10015            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10016                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10017            } else {
10018                oomAdj = Integer.toString(r.setAdj);
10019            }
10020            String schedGroup;
10021            switch (r.setSchedGroup) {
10022                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10023                    schedGroup = "B";
10024                    break;
10025                case Process.THREAD_GROUP_DEFAULT:
10026                    schedGroup = "F";
10027                    break;
10028                default:
10029                    schedGroup = Integer.toString(r.setSchedGroup);
10030                    break;
10031            }
10032            String foreground;
10033            if (r.foregroundActivities) {
10034                foreground = "A";
10035            } else if (r.foregroundServices) {
10036                foreground = "S";
10037            } else {
10038                foreground = " ";
10039            }
10040            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10041                    prefix, (r.persistent ? persistentLabel : normalLabel),
10042                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10043                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10044            if (r.adjSource != null || r.adjTarget != null) {
10045                pw.print(prefix);
10046                pw.print("    ");
10047                if (r.adjTarget instanceof ComponentName) {
10048                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10049                } else if (r.adjTarget != null) {
10050                    pw.print(r.adjTarget.toString());
10051                } else {
10052                    pw.print("{null}");
10053                }
10054                pw.print("<=");
10055                if (r.adjSource instanceof ProcessRecord) {
10056                    pw.print("Proc{");
10057                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10058                    pw.println("}");
10059                } else if (r.adjSource != null) {
10060                    pw.println(r.adjSource.toString());
10061                } else {
10062                    pw.println("{null}");
10063                }
10064            }
10065            if (inclDetails) {
10066                pw.print(prefix);
10067                pw.print("    ");
10068                pw.print("oom: max="); pw.print(r.maxAdj);
10069                pw.print(" hidden="); pw.print(r.hiddenAdj);
10070                pw.print(" empty="); pw.print(r.emptyAdj);
10071                pw.print(" curRaw="); pw.print(r.curRawAdj);
10072                pw.print(" setRaw="); pw.print(r.setRawAdj);
10073                pw.print(" cur="); pw.print(r.curAdj);
10074                pw.print(" set="); pw.println(r.setAdj);
10075                pw.print(prefix);
10076                pw.print("    ");
10077                pw.print("keeping="); pw.print(r.keeping);
10078                pw.print(" hidden="); pw.print(r.hidden);
10079                pw.print(" empty="); pw.print(r.empty);
10080                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10081
10082                if (!r.keeping) {
10083                    if (r.lastWakeTime != 0) {
10084                        long wtime;
10085                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10086                        synchronized (stats) {
10087                            wtime = stats.getProcessWakeTime(r.info.uid,
10088                                    r.pid, curRealtime);
10089                        }
10090                        long timeUsed = wtime - r.lastWakeTime;
10091                        pw.print(prefix);
10092                        pw.print("    ");
10093                        pw.print("keep awake over ");
10094                        TimeUtils.formatDuration(realtimeSince, pw);
10095                        pw.print(" used ");
10096                        TimeUtils.formatDuration(timeUsed, pw);
10097                        pw.print(" (");
10098                        pw.print((timeUsed*100)/realtimeSince);
10099                        pw.println("%)");
10100                    }
10101                    if (r.lastCpuTime != 0) {
10102                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10103                        pw.print(prefix);
10104                        pw.print("    ");
10105                        pw.print("run cpu over ");
10106                        TimeUtils.formatDuration(uptimeSince, pw);
10107                        pw.print(" used ");
10108                        TimeUtils.formatDuration(timeUsed, pw);
10109                        pw.print(" (");
10110                        pw.print((timeUsed*100)/uptimeSince);
10111                        pw.println("%)");
10112                    }
10113                }
10114            }
10115        }
10116        return true;
10117    }
10118
10119    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10120        ArrayList<ProcessRecord> procs;
10121        synchronized (this) {
10122            if (args != null && args.length > start
10123                    && args[start].charAt(0) != '-') {
10124                procs = new ArrayList<ProcessRecord>();
10125                int pid = -1;
10126                try {
10127                    pid = Integer.parseInt(args[start]);
10128                } catch (NumberFormatException e) {
10129
10130                }
10131                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10132                    ProcessRecord proc = mLruProcesses.get(i);
10133                    if (proc.pid == pid) {
10134                        procs.add(proc);
10135                    } else if (proc.processName.equals(args[start])) {
10136                        procs.add(proc);
10137                    }
10138                }
10139                if (procs.size() <= 0) {
10140                    pw.println("No process found for: " + args[start]);
10141                    return null;
10142                }
10143            } else {
10144                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10145            }
10146        }
10147        return procs;
10148    }
10149
10150    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10151            PrintWriter pw, String[] args) {
10152        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10153        if (procs == null) {
10154            return;
10155        }
10156
10157        long uptime = SystemClock.uptimeMillis();
10158        long realtime = SystemClock.elapsedRealtime();
10159        pw.println("Applications Graphics Acceleration Info:");
10160        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10161
10162        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10163            ProcessRecord r = procs.get(i);
10164            if (r.thread != null) {
10165                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10166                pw.flush();
10167                try {
10168                    TransferPipe tp = new TransferPipe();
10169                    try {
10170                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10171                        tp.go(fd);
10172                    } finally {
10173                        tp.kill();
10174                    }
10175                } catch (IOException e) {
10176                    pw.println("Failure while dumping the app: " + r);
10177                    pw.flush();
10178                } catch (RemoteException e) {
10179                    pw.println("Got a RemoteException while dumping the app " + r);
10180                    pw.flush();
10181                }
10182            }
10183        }
10184    }
10185
10186    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10187        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10188        if (procs == null) {
10189            return;
10190        }
10191
10192        pw.println("Applications Database Info:");
10193
10194        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10195            ProcessRecord r = procs.get(i);
10196            if (r.thread != null) {
10197                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10198                pw.flush();
10199                try {
10200                    TransferPipe tp = new TransferPipe();
10201                    try {
10202                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10203                        tp.go(fd);
10204                    } finally {
10205                        tp.kill();
10206                    }
10207                } catch (IOException e) {
10208                    pw.println("Failure while dumping the app: " + r);
10209                    pw.flush();
10210                } catch (RemoteException e) {
10211                    pw.println("Got a RemoteException while dumping the app " + r);
10212                    pw.flush();
10213                }
10214            }
10215        }
10216    }
10217
10218    final static class MemItem {
10219        final String label;
10220        final String shortLabel;
10221        final long pss;
10222        final int id;
10223        ArrayList<MemItem> subitems;
10224
10225        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10226            label = _label;
10227            shortLabel = _shortLabel;
10228            pss = _pss;
10229            id = _id;
10230        }
10231    }
10232
10233    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10234            boolean sort) {
10235        if (sort) {
10236            Collections.sort(items, new Comparator<MemItem>() {
10237                @Override
10238                public int compare(MemItem lhs, MemItem rhs) {
10239                    if (lhs.pss < rhs.pss) {
10240                        return 1;
10241                    } else if (lhs.pss > rhs.pss) {
10242                        return -1;
10243                    }
10244                    return 0;
10245                }
10246            });
10247        }
10248
10249        for (int i=0; i<items.size(); i++) {
10250            MemItem mi = items.get(i);
10251            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10252            if (mi.subitems != null) {
10253                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10254            }
10255        }
10256    }
10257
10258    // These are in KB.
10259    static final long[] DUMP_MEM_BUCKETS = new long[] {
10260        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10261        120*1024, 160*1024, 200*1024,
10262        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10263        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10264    };
10265
10266    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10267            boolean stackLike) {
10268        int start = label.lastIndexOf('.');
10269        if (start >= 0) start++;
10270        else start = 0;
10271        int end = label.length();
10272        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10273            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10274                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10275                out.append(bucket);
10276                out.append(stackLike ? "MB." : "MB ");
10277                out.append(label, start, end);
10278                return;
10279            }
10280        }
10281        out.append(memKB/1024);
10282        out.append(stackLike ? "MB." : "MB ");
10283        out.append(label, start, end);
10284    }
10285
10286    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10287            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10288            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10289            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10290            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10291    };
10292    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10293            "System", "Persistent", "Foreground",
10294            "Visible", "Perceptible", "Heavy Weight",
10295            "Backup", "A Services", "Home", "Previous",
10296            "B Services", "Background"
10297    };
10298
10299    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10300            PrintWriter pw, String prefix, String[] args, boolean brief,
10301            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10302        boolean dumpAll = false;
10303        boolean oomOnly = false;
10304
10305        int opti = 0;
10306        while (opti < args.length) {
10307            String opt = args[opti];
10308            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10309                break;
10310            }
10311            opti++;
10312            if ("-a".equals(opt)) {
10313                dumpAll = true;
10314            } else if ("--oom".equals(opt)) {
10315                oomOnly = true;
10316            } else if ("-h".equals(opt)) {
10317                pw.println("meminfo dump options: [-a] [--oom] [process]");
10318                pw.println("  -a: include all available information for each process.");
10319                pw.println("  --oom: only show processes organized by oom adj.");
10320                pw.println("If [process] is specified it can be the name or ");
10321                pw.println("pid of a specific process to dump.");
10322                return;
10323            } else {
10324                pw.println("Unknown argument: " + opt + "; use -h for help");
10325            }
10326        }
10327
10328        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10329        if (procs == null) {
10330            return;
10331        }
10332
10333        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10334        long uptime = SystemClock.uptimeMillis();
10335        long realtime = SystemClock.elapsedRealtime();
10336
10337        if (procs.size() == 1 || isCheckinRequest) {
10338            dumpAll = true;
10339        }
10340
10341        if (isCheckinRequest) {
10342            // short checkin version
10343            pw.println(uptime + "," + realtime);
10344            pw.flush();
10345        } else {
10346            pw.println("Applications Memory Usage (kB):");
10347            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10348        }
10349
10350        String[] innerArgs = new String[args.length-opti];
10351        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10352
10353        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10354        long nativePss=0, dalvikPss=0, otherPss=0;
10355        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10356
10357        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10358        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10359                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10360
10361        long totalPss = 0;
10362
10363        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10364            ProcessRecord r = procs.get(i);
10365            if (r.thread != null) {
10366                if (!isCheckinRequest && dumpAll) {
10367                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10368                    pw.flush();
10369                }
10370                Debug.MemoryInfo mi = null;
10371                if (dumpAll) {
10372                    try {
10373                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10374                    } catch (RemoteException e) {
10375                        if (!isCheckinRequest) {
10376                            pw.println("Got RemoteException!");
10377                            pw.flush();
10378                        }
10379                    }
10380                } else {
10381                    mi = new Debug.MemoryInfo();
10382                    Debug.getMemoryInfo(r.pid, mi);
10383                }
10384
10385                if (!isCheckinRequest && mi != null) {
10386                    long myTotalPss = mi.getTotalPss();
10387                    totalPss += myTotalPss;
10388                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10389                            r.processName, myTotalPss, 0);
10390                    procMems.add(pssItem);
10391
10392                    nativePss += mi.nativePss;
10393                    dalvikPss += mi.dalvikPss;
10394                    otherPss += mi.otherPss;
10395                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10396                        long mem = mi.getOtherPss(j);
10397                        miscPss[j] += mem;
10398                        otherPss -= mem;
10399                    }
10400
10401                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10402                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10403                                || oomIndex == (oomPss.length-1)) {
10404                            oomPss[oomIndex] += myTotalPss;
10405                            if (oomProcs[oomIndex] == null) {
10406                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10407                            }
10408                            oomProcs[oomIndex].add(pssItem);
10409                            break;
10410                        }
10411                    }
10412                }
10413            }
10414        }
10415
10416        if (!isCheckinRequest && procs.size() > 1) {
10417            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10418
10419            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10420            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10421            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10422            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10423                String label = Debug.MemoryInfo.getOtherLabel(j);
10424                catMems.add(new MemItem(label, label, miscPss[j], j));
10425            }
10426
10427            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10428            for (int j=0; j<oomPss.length; j++) {
10429                if (oomPss[j] != 0) {
10430                    String label = DUMP_MEM_OOM_LABEL[j];
10431                    MemItem item = new MemItem(label, label, oomPss[j],
10432                            DUMP_MEM_OOM_ADJ[j]);
10433                    item.subitems = oomProcs[j];
10434                    oomMems.add(item);
10435                }
10436            }
10437
10438            if (outTag != null || outStack != null) {
10439                if (outTag != null) {
10440                    appendMemBucket(outTag, totalPss, "total", false);
10441                }
10442                if (outStack != null) {
10443                    appendMemBucket(outStack, totalPss, "total", true);
10444                }
10445                boolean firstLine = true;
10446                for (int i=0; i<oomMems.size(); i++) {
10447                    MemItem miCat = oomMems.get(i);
10448                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10449                        continue;
10450                    }
10451                    if (miCat.id < ProcessList.SERVICE_ADJ
10452                            || miCat.id == ProcessList.HOME_APP_ADJ
10453                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10454                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10455                            outTag.append(" / ");
10456                        }
10457                        if (outStack != null) {
10458                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10459                                if (firstLine) {
10460                                    outStack.append(":");
10461                                    firstLine = false;
10462                                }
10463                                outStack.append("\n\t at ");
10464                            } else {
10465                                outStack.append("$");
10466                            }
10467                        }
10468                        for (int j=0; j<miCat.subitems.size(); j++) {
10469                            MemItem mi = miCat.subitems.get(j);
10470                            if (j > 0) {
10471                                if (outTag != null) {
10472                                    outTag.append(" ");
10473                                }
10474                                if (outStack != null) {
10475                                    outStack.append("$");
10476                                }
10477                            }
10478                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10479                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10480                            }
10481                            if (outStack != null) {
10482                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10483                            }
10484                        }
10485                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10486                            outStack.append("(");
10487                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10488                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10489                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10490                                    outStack.append(":");
10491                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10492                                }
10493                            }
10494                            outStack.append(")");
10495                        }
10496                    }
10497                }
10498            }
10499
10500            if (!brief && !oomOnly) {
10501                pw.println();
10502                pw.println("Total PSS by process:");
10503                dumpMemItems(pw, "  ", procMems, true);
10504                pw.println();
10505            }
10506            pw.println("Total PSS by OOM adjustment:");
10507            dumpMemItems(pw, "  ", oomMems, false);
10508            if (!oomOnly) {
10509                PrintWriter out = categoryPw != null ? categoryPw : pw;
10510                out.println();
10511                out.println("Total PSS by category:");
10512                dumpMemItems(out, "  ", catMems, true);
10513            }
10514            pw.println();
10515            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10516            final int[] SINGLE_LONG_FORMAT = new int[] {
10517                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10518            };
10519            long[] longOut = new long[1];
10520            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10521                    SINGLE_LONG_FORMAT, null, longOut, null);
10522            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10523            longOut[0] = 0;
10524            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10525                    SINGLE_LONG_FORMAT, null, longOut, null);
10526            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10527            longOut[0] = 0;
10528            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10529                    SINGLE_LONG_FORMAT, null, longOut, null);
10530            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10531            longOut[0] = 0;
10532            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10533                    SINGLE_LONG_FORMAT, null, longOut, null);
10534            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10535            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10536                    pw.print(shared); pw.println(" kB");
10537            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10538                    pw.print(voltile); pw.println(" kB volatile");
10539        }
10540    }
10541
10542    /**
10543     * Searches array of arguments for the specified string
10544     * @param args array of argument strings
10545     * @param value value to search for
10546     * @return true if the value is contained in the array
10547     */
10548    private static boolean scanArgs(String[] args, String value) {
10549        if (args != null) {
10550            for (String arg : args) {
10551                if (value.equals(arg)) {
10552                    return true;
10553                }
10554            }
10555        }
10556        return false;
10557    }
10558
10559    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10560            ContentProviderRecord cpr, boolean always) {
10561        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10562
10563        if (!inLaunching || always) {
10564            synchronized (cpr) {
10565                cpr.launchingApp = null;
10566                cpr.notifyAll();
10567            }
10568            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10569            String names[] = cpr.info.authority.split(";");
10570            for (int j = 0; j < names.length; j++) {
10571                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10572            }
10573        }
10574
10575        for (int i=0; i<cpr.connections.size(); i++) {
10576            ContentProviderConnection conn = cpr.connections.get(i);
10577            if (conn.waiting) {
10578                // If this connection is waiting for the provider, then we don't
10579                // need to mess with its process unless we are always removing
10580                // or for some reason the provider is not currently launching.
10581                if (inLaunching && !always) {
10582                    continue;
10583                }
10584            }
10585            ProcessRecord capp = conn.client;
10586            conn.dead = true;
10587            if (conn.stableCount > 0) {
10588                if (!capp.persistent && capp.thread != null
10589                        && capp.pid != 0
10590                        && capp.pid != MY_PID) {
10591                    Slog.i(TAG, "Kill " + capp.processName
10592                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10593                            + " in dying process " + (proc != null ? proc.processName : "??"));
10594                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10595                            capp.processName, capp.setAdj, "dying provider "
10596                                    + cpr.name.toShortString());
10597                    Process.killProcessQuiet(capp.pid);
10598                }
10599            } else if (capp.thread != null && conn.provider.provider != null) {
10600                try {
10601                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10602                } catch (RemoteException e) {
10603                }
10604                // In the protocol here, we don't expect the client to correctly
10605                // clean up this connection, we'll just remove it.
10606                cpr.connections.remove(i);
10607                conn.client.conProviders.remove(conn);
10608            }
10609        }
10610
10611        if (inLaunching && always) {
10612            mLaunchingProviders.remove(cpr);
10613        }
10614        return inLaunching;
10615    }
10616
10617    /**
10618     * Main code for cleaning up a process when it has gone away.  This is
10619     * called both as a result of the process dying, or directly when stopping
10620     * a process when running in single process mode.
10621     */
10622    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10623            boolean restarting, boolean allowRestart, int index) {
10624        if (index >= 0) {
10625            mLruProcesses.remove(index);
10626        }
10627
10628        mProcessesToGc.remove(app);
10629
10630        // Dismiss any open dialogs.
10631        if (app.crashDialog != null) {
10632            app.crashDialog.dismiss();
10633            app.crashDialog = null;
10634        }
10635        if (app.anrDialog != null) {
10636            app.anrDialog.dismiss();
10637            app.anrDialog = null;
10638        }
10639        if (app.waitDialog != null) {
10640            app.waitDialog.dismiss();
10641            app.waitDialog = null;
10642        }
10643
10644        app.crashing = false;
10645        app.notResponding = false;
10646
10647        app.resetPackageList();
10648        app.unlinkDeathRecipient();
10649        app.thread = null;
10650        app.forcingToForeground = null;
10651        app.foregroundServices = false;
10652        app.foregroundActivities = false;
10653        app.hasShownUi = false;
10654        app.hasAboveClient = false;
10655
10656        mServices.killServicesLocked(app, allowRestart);
10657
10658        boolean restart = false;
10659
10660        // Remove published content providers.
10661        if (!app.pubProviders.isEmpty()) {
10662            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10663            while (it.hasNext()) {
10664                ContentProviderRecord cpr = it.next();
10665
10666                final boolean always = app.bad || !allowRestart;
10667                if (removeDyingProviderLocked(app, cpr, always) || always) {
10668                    // We left the provider in the launching list, need to
10669                    // restart it.
10670                    restart = true;
10671                }
10672
10673                cpr.provider = null;
10674                cpr.proc = null;
10675            }
10676            app.pubProviders.clear();
10677        }
10678
10679        // Take care of any launching providers waiting for this process.
10680        if (checkAppInLaunchingProvidersLocked(app, false)) {
10681            restart = true;
10682        }
10683
10684        // Unregister from connected content providers.
10685        if (!app.conProviders.isEmpty()) {
10686            for (int i=0; i<app.conProviders.size(); i++) {
10687                ContentProviderConnection conn = app.conProviders.get(i);
10688                conn.provider.connections.remove(conn);
10689            }
10690            app.conProviders.clear();
10691        }
10692
10693        // At this point there may be remaining entries in mLaunchingProviders
10694        // where we were the only one waiting, so they are no longer of use.
10695        // Look for these and clean up if found.
10696        // XXX Commented out for now.  Trying to figure out a way to reproduce
10697        // the actual situation to identify what is actually going on.
10698        if (false) {
10699            for (int i=0; i<mLaunchingProviders.size(); i++) {
10700                ContentProviderRecord cpr = (ContentProviderRecord)
10701                        mLaunchingProviders.get(i);
10702                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10703                    synchronized (cpr) {
10704                        cpr.launchingApp = null;
10705                        cpr.notifyAll();
10706                    }
10707                }
10708            }
10709        }
10710
10711        skipCurrentReceiverLocked(app);
10712
10713        // Unregister any receivers.
10714        if (app.receivers.size() > 0) {
10715            Iterator<ReceiverList> it = app.receivers.iterator();
10716            while (it.hasNext()) {
10717                removeReceiverLocked(it.next());
10718            }
10719            app.receivers.clear();
10720        }
10721
10722        // If the app is undergoing backup, tell the backup manager about it
10723        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10724            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10725            try {
10726                IBackupManager bm = IBackupManager.Stub.asInterface(
10727                        ServiceManager.getService(Context.BACKUP_SERVICE));
10728                bm.agentDisconnected(app.info.packageName);
10729            } catch (RemoteException e) {
10730                // can't happen; backup manager is local
10731            }
10732        }
10733
10734        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10735            ProcessChangeItem item = mPendingProcessChanges.get(i);
10736            if (item.pid == app.pid) {
10737                mPendingProcessChanges.remove(i);
10738                mAvailProcessChanges.add(item);
10739            }
10740        }
10741        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10742
10743        // If the caller is restarting this app, then leave it in its
10744        // current lists and let the caller take care of it.
10745        if (restarting) {
10746            return;
10747        }
10748
10749        if (!app.persistent || app.isolated) {
10750            if (DEBUG_PROCESSES) Slog.v(TAG,
10751                    "Removing non-persistent process during cleanup: " + app);
10752            mProcessNames.remove(app.processName, app.uid);
10753            mIsolatedProcesses.remove(app.uid);
10754            if (mHeavyWeightProcess == app) {
10755                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10756                        mHeavyWeightProcess.userId, 0));
10757                mHeavyWeightProcess = null;
10758            }
10759        } else if (!app.removed) {
10760            // This app is persistent, so we need to keep its record around.
10761            // If it is not already on the pending app list, add it there
10762            // and start a new process for it.
10763            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10764                mPersistentStartingProcesses.add(app);
10765                restart = true;
10766            }
10767        }
10768        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10769                "Clean-up removing on hold: " + app);
10770        mProcessesOnHold.remove(app);
10771
10772        if (app == mHomeProcess) {
10773            mHomeProcess = null;
10774        }
10775        if (app == mPreviousProcess) {
10776            mPreviousProcess = null;
10777        }
10778
10779        if (restart && !app.isolated) {
10780            // We have components that still need to be running in the
10781            // process, so re-launch it.
10782            mProcessNames.put(app.processName, app.uid, app);
10783            startProcessLocked(app, "restart", app.processName);
10784        } else if (app.pid > 0 && app.pid != MY_PID) {
10785            // Goodbye!
10786            synchronized (mPidsSelfLocked) {
10787                mPidsSelfLocked.remove(app.pid);
10788                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10789            }
10790            app.setPid(0);
10791        }
10792    }
10793
10794    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10795        // Look through the content providers we are waiting to have launched,
10796        // and if any run in this process then either schedule a restart of
10797        // the process or kill the client waiting for it if this process has
10798        // gone bad.
10799        int NL = mLaunchingProviders.size();
10800        boolean restart = false;
10801        for (int i=0; i<NL; i++) {
10802            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10803            if (cpr.launchingApp == app) {
10804                if (!alwaysBad && !app.bad) {
10805                    restart = true;
10806                } else {
10807                    removeDyingProviderLocked(app, cpr, true);
10808                    // cpr should have been removed from mLaunchingProviders
10809                    NL = mLaunchingProviders.size();
10810                    i--;
10811                }
10812            }
10813        }
10814        return restart;
10815    }
10816
10817    // =========================================================
10818    // SERVICES
10819    // =========================================================
10820
10821    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10822            int flags) {
10823        enforceNotIsolatedCaller("getServices");
10824        synchronized (this) {
10825            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10826        }
10827    }
10828
10829    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10830        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10831        synchronized (this) {
10832            return mServices.getRunningServiceControlPanelLocked(name);
10833        }
10834    }
10835
10836    public ComponentName startService(IApplicationThread caller, Intent service,
10837            String resolvedType, int userId) {
10838        enforceNotIsolatedCaller("startService");
10839        // Refuse possible leaked file descriptors
10840        if (service != null && service.hasFileDescriptors() == true) {
10841            throw new IllegalArgumentException("File descriptors passed in Intent");
10842        }
10843
10844        if (DEBUG_SERVICE)
10845            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10846        synchronized(this) {
10847            final int callingPid = Binder.getCallingPid();
10848            final int callingUid = Binder.getCallingUid();
10849            checkValidCaller(callingUid, userId);
10850            final long origId = Binder.clearCallingIdentity();
10851            ComponentName res = mServices.startServiceLocked(caller, service,
10852                    resolvedType, callingPid, callingUid, userId);
10853            Binder.restoreCallingIdentity(origId);
10854            return res;
10855        }
10856    }
10857
10858    ComponentName startServiceInPackage(int uid,
10859            Intent service, String resolvedType, int userId) {
10860        synchronized(this) {
10861            if (DEBUG_SERVICE)
10862                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10863            final long origId = Binder.clearCallingIdentity();
10864            ComponentName res = mServices.startServiceLocked(null, service,
10865                    resolvedType, -1, uid, userId);
10866            Binder.restoreCallingIdentity(origId);
10867            return res;
10868        }
10869    }
10870
10871    public int stopService(IApplicationThread caller, Intent service,
10872            String resolvedType, int userId) {
10873        enforceNotIsolatedCaller("stopService");
10874        // Refuse possible leaked file descriptors
10875        if (service != null && service.hasFileDescriptors() == true) {
10876            throw new IllegalArgumentException("File descriptors passed in Intent");
10877        }
10878
10879        checkValidCaller(Binder.getCallingUid(), userId);
10880
10881        synchronized(this) {
10882            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10883        }
10884    }
10885
10886    public IBinder peekService(Intent service, String resolvedType) {
10887        enforceNotIsolatedCaller("peekService");
10888        // Refuse possible leaked file descriptors
10889        if (service != null && service.hasFileDescriptors() == true) {
10890            throw new IllegalArgumentException("File descriptors passed in Intent");
10891        }
10892        synchronized(this) {
10893            return mServices.peekServiceLocked(service, resolvedType);
10894        }
10895    }
10896
10897    public boolean stopServiceToken(ComponentName className, IBinder token,
10898            int startId) {
10899        synchronized(this) {
10900            return mServices.stopServiceTokenLocked(className, token, startId);
10901        }
10902    }
10903
10904    public void setServiceForeground(ComponentName className, IBinder token,
10905            int id, Notification notification, boolean removeNotification) {
10906        synchronized(this) {
10907            mServices.setServiceForegroundLocked(className, token, id, notification,
10908                    removeNotification);
10909        }
10910    }
10911
10912    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10913            boolean requireFull, String name, String callerPackage) {
10914        final int callingUserId = UserHandle.getUserId(callingUid);
10915        if (callingUserId != userId) {
10916            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10917                if ((requireFull || checkComponentPermission(
10918                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10919                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10920                        && checkComponentPermission(
10921                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10922                                callingPid, callingUid, -1, true)
10923                                != PackageManager.PERMISSION_GRANTED) {
10924                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10925                        // In this case, they would like to just execute as their
10926                        // owner user instead of failing.
10927                        userId = callingUserId;
10928                    } else {
10929                        StringBuilder builder = new StringBuilder(128);
10930                        builder.append("Permission Denial: ");
10931                        builder.append(name);
10932                        if (callerPackage != null) {
10933                            builder.append(" from ");
10934                            builder.append(callerPackage);
10935                        }
10936                        builder.append(" asks to run as user ");
10937                        builder.append(userId);
10938                        builder.append(" but is calling from user ");
10939                        builder.append(UserHandle.getUserId(callingUid));
10940                        builder.append("; this requires ");
10941                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10942                        if (!requireFull) {
10943                            builder.append(" or ");
10944                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10945                        }
10946                        String msg = builder.toString();
10947                        Slog.w(TAG, msg);
10948                        throw new SecurityException(msg);
10949                    }
10950                }
10951            }
10952            if (userId == UserHandle.USER_CURRENT
10953                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10954                // Note that we may be accessing this outside of a lock...
10955                // shouldn't be a big deal, if this is being called outside
10956                // of a locked context there is intrinsically a race with
10957                // the value the caller will receive and someone else changing it.
10958                userId = mCurrentUserId;
10959            }
10960            if (!allowAll && userId < 0) {
10961                throw new IllegalArgumentException(
10962                        "Call does not support special user #" + userId);
10963            }
10964        }
10965        return userId;
10966    }
10967
10968    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10969            String className, int flags) {
10970        boolean result = false;
10971        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10972            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10973                if (ActivityManager.checkUidPermission(
10974                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10975                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10976                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10977                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10978                            + " requests FLAG_SINGLE_USER, but app does not hold "
10979                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10980                    Slog.w(TAG, msg);
10981                    throw new SecurityException(msg);
10982                }
10983                result = true;
10984            }
10985        } else if (componentProcessName == aInfo.packageName) {
10986            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10987        } else if ("system".equals(componentProcessName)) {
10988            result = true;
10989        }
10990        if (DEBUG_MU) {
10991            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10992                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10993        }
10994        return result;
10995    }
10996
10997    public int bindService(IApplicationThread caller, IBinder token,
10998            Intent service, String resolvedType,
10999            IServiceConnection connection, int flags, int userId) {
11000        enforceNotIsolatedCaller("bindService");
11001        // Refuse possible leaked file descriptors
11002        if (service != null && service.hasFileDescriptors() == true) {
11003            throw new IllegalArgumentException("File descriptors passed in Intent");
11004        }
11005
11006        synchronized(this) {
11007            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11008                    connection, flags, userId);
11009        }
11010    }
11011
11012    public boolean unbindService(IServiceConnection connection) {
11013        synchronized (this) {
11014            return mServices.unbindServiceLocked(connection);
11015        }
11016    }
11017
11018    public void publishService(IBinder token, Intent intent, IBinder service) {
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            if (!(token instanceof ServiceRecord)) {
11026                throw new IllegalArgumentException("Invalid service token");
11027            }
11028            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11029        }
11030    }
11031
11032    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11033        // Refuse possible leaked file descriptors
11034        if (intent != null && intent.hasFileDescriptors() == true) {
11035            throw new IllegalArgumentException("File descriptors passed in Intent");
11036        }
11037
11038        synchronized(this) {
11039            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11040        }
11041    }
11042
11043    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11044        synchronized(this) {
11045            if (!(token instanceof ServiceRecord)) {
11046                throw new IllegalArgumentException("Invalid service token");
11047            }
11048            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11049        }
11050    }
11051
11052    // =========================================================
11053    // BACKUP AND RESTORE
11054    // =========================================================
11055
11056    // Cause the target app to be launched if necessary and its backup agent
11057    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11058    // activity manager to announce its creation.
11059    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11060        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11061        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11062
11063        synchronized(this) {
11064            // !!! TODO: currently no check here that we're already bound
11065            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11066            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11067            synchronized (stats) {
11068                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11069            }
11070
11071            // Backup agent is now in use, its package can't be stopped.
11072            try {
11073                AppGlobals.getPackageManager().setPackageStoppedState(
11074                        app.packageName, false, UserHandle.getUserId(app.uid));
11075            } catch (RemoteException e) {
11076            } catch (IllegalArgumentException e) {
11077                Slog.w(TAG, "Failed trying to unstop package "
11078                        + app.packageName + ": " + e);
11079            }
11080
11081            BackupRecord r = new BackupRecord(ss, app, backupMode);
11082            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11083                    ? new ComponentName(app.packageName, app.backupAgentName)
11084                    : new ComponentName("android", "FullBackupAgent");
11085            // startProcessLocked() returns existing proc's record if it's already running
11086            ProcessRecord proc = startProcessLocked(app.processName, app,
11087                    false, 0, "backup", hostingName, false, false);
11088            if (proc == null) {
11089                Slog.e(TAG, "Unable to start backup agent process " + r);
11090                return false;
11091            }
11092
11093            r.app = proc;
11094            mBackupTarget = r;
11095            mBackupAppName = app.packageName;
11096
11097            // Try not to kill the process during backup
11098            updateOomAdjLocked(proc);
11099
11100            // If the process is already attached, schedule the creation of the backup agent now.
11101            // If it is not yet live, this will be done when it attaches to the framework.
11102            if (proc.thread != null) {
11103                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11104                try {
11105                    proc.thread.scheduleCreateBackupAgent(app,
11106                            compatibilityInfoForPackageLocked(app), backupMode);
11107                } catch (RemoteException e) {
11108                    // Will time out on the backup manager side
11109                }
11110            } else {
11111                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11112            }
11113            // Invariants: at this point, the target app process exists and the application
11114            // is either already running or in the process of coming up.  mBackupTarget and
11115            // mBackupAppName describe the app, so that when it binds back to the AM we
11116            // know that it's scheduled for a backup-agent operation.
11117        }
11118
11119        return true;
11120    }
11121
11122    // A backup agent has just come up
11123    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11124        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11125                + " = " + agent);
11126
11127        synchronized(this) {
11128            if (!agentPackageName.equals(mBackupAppName)) {
11129                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11130                return;
11131            }
11132        }
11133
11134        long oldIdent = Binder.clearCallingIdentity();
11135        try {
11136            IBackupManager bm = IBackupManager.Stub.asInterface(
11137                    ServiceManager.getService(Context.BACKUP_SERVICE));
11138            bm.agentConnected(agentPackageName, agent);
11139        } catch (RemoteException e) {
11140            // can't happen; the backup manager service is local
11141        } catch (Exception e) {
11142            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11143            e.printStackTrace();
11144        } finally {
11145            Binder.restoreCallingIdentity(oldIdent);
11146        }
11147    }
11148
11149    // done with this agent
11150    public void unbindBackupAgent(ApplicationInfo appInfo) {
11151        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11152        if (appInfo == null) {
11153            Slog.w(TAG, "unbind backup agent for null app");
11154            return;
11155        }
11156
11157        synchronized(this) {
11158            if (mBackupAppName == null) {
11159                Slog.w(TAG, "Unbinding backup agent with no active backup");
11160                return;
11161            }
11162
11163            if (!mBackupAppName.equals(appInfo.packageName)) {
11164                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11165                return;
11166            }
11167
11168            ProcessRecord proc = mBackupTarget.app;
11169            mBackupTarget = null;
11170            mBackupAppName = null;
11171
11172            // Not backing this app up any more; reset its OOM adjustment
11173            updateOomAdjLocked(proc);
11174
11175            // If the app crashed during backup, 'thread' will be null here
11176            if (proc.thread != null) {
11177                try {
11178                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11179                            compatibilityInfoForPackageLocked(appInfo));
11180                } catch (Exception e) {
11181                    Slog.e(TAG, "Exception when unbinding backup agent:");
11182                    e.printStackTrace();
11183                }
11184            }
11185        }
11186    }
11187    // =========================================================
11188    // BROADCASTS
11189    // =========================================================
11190
11191    private final List getStickiesLocked(String action, IntentFilter filter,
11192            List cur, int userId) {
11193        final ContentResolver resolver = mContext.getContentResolver();
11194        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11195        if (stickies == null) {
11196            return cur;
11197        }
11198        final ArrayList<Intent> list = stickies.get(action);
11199        if (list == null) {
11200            return cur;
11201        }
11202        int N = list.size();
11203        for (int i=0; i<N; i++) {
11204            Intent intent = list.get(i);
11205            if (filter.match(resolver, intent, true, TAG) >= 0) {
11206                if (cur == null) {
11207                    cur = new ArrayList<Intent>();
11208                }
11209                cur.add(intent);
11210            }
11211        }
11212        return cur;
11213    }
11214
11215    boolean isPendingBroadcastProcessLocked(int pid) {
11216        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11217                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11218    }
11219
11220    void skipPendingBroadcastLocked(int pid) {
11221            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11222            for (BroadcastQueue queue : mBroadcastQueues) {
11223                queue.skipPendingBroadcastLocked(pid);
11224            }
11225    }
11226
11227    // The app just attached; send any pending broadcasts that it should receive
11228    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11229        boolean didSomething = false;
11230        for (BroadcastQueue queue : mBroadcastQueues) {
11231            didSomething |= queue.sendPendingBroadcastsLocked(app);
11232        }
11233        return didSomething;
11234    }
11235
11236    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11237            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11238        enforceNotIsolatedCaller("registerReceiver");
11239        int callingUid;
11240        int callingPid;
11241        synchronized(this) {
11242            ProcessRecord callerApp = null;
11243            if (caller != null) {
11244                callerApp = getRecordForAppLocked(caller);
11245                if (callerApp == null) {
11246                    throw new SecurityException(
11247                            "Unable to find app for caller " + caller
11248                            + " (pid=" + Binder.getCallingPid()
11249                            + ") when registering receiver " + receiver);
11250                }
11251                if (callerApp.info.uid != Process.SYSTEM_UID &&
11252                        !callerApp.pkgList.contains(callerPackage)) {
11253                    throw new SecurityException("Given caller package " + callerPackage
11254                            + " is not running in process " + callerApp);
11255                }
11256                callingUid = callerApp.info.uid;
11257                callingPid = callerApp.pid;
11258            } else {
11259                callerPackage = null;
11260                callingUid = Binder.getCallingUid();
11261                callingPid = Binder.getCallingPid();
11262            }
11263
11264            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11265                    true, true, "registerReceiver", callerPackage);
11266
11267            List allSticky = null;
11268
11269            // Look for any matching sticky broadcasts...
11270            Iterator actions = filter.actionsIterator();
11271            if (actions != null) {
11272                while (actions.hasNext()) {
11273                    String action = (String)actions.next();
11274                    allSticky = getStickiesLocked(action, filter, allSticky,
11275                            UserHandle.USER_ALL);
11276                    allSticky = getStickiesLocked(action, filter, allSticky,
11277                            UserHandle.getUserId(callingUid));
11278                }
11279            } else {
11280                allSticky = getStickiesLocked(null, filter, allSticky,
11281                        UserHandle.USER_ALL);
11282                allSticky = getStickiesLocked(null, filter, allSticky,
11283                        UserHandle.getUserId(callingUid));
11284            }
11285
11286            // The first sticky in the list is returned directly back to
11287            // the client.
11288            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11289
11290            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11291                    + ": " + sticky);
11292
11293            if (receiver == null) {
11294                return sticky;
11295            }
11296
11297            ReceiverList rl
11298                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11299            if (rl == null) {
11300                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11301                        userId, receiver);
11302                if (rl.app != null) {
11303                    rl.app.receivers.add(rl);
11304                } else {
11305                    try {
11306                        receiver.asBinder().linkToDeath(rl, 0);
11307                    } catch (RemoteException e) {
11308                        return sticky;
11309                    }
11310                    rl.linkedToDeath = true;
11311                }
11312                mRegisteredReceivers.put(receiver.asBinder(), rl);
11313            } else if (rl.uid != callingUid) {
11314                throw new IllegalArgumentException(
11315                        "Receiver requested to register for uid " + callingUid
11316                        + " was previously registered for uid " + rl.uid);
11317            } else if (rl.pid != callingPid) {
11318                throw new IllegalArgumentException(
11319                        "Receiver requested to register for pid " + callingPid
11320                        + " was previously registered for pid " + rl.pid);
11321            } else if (rl.userId != userId) {
11322                throw new IllegalArgumentException(
11323                        "Receiver requested to register for user " + userId
11324                        + " was previously registered for user " + rl.userId);
11325            }
11326            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11327                    permission, callingUid, userId);
11328            rl.add(bf);
11329            if (!bf.debugCheck()) {
11330                Slog.w(TAG, "==> For Dynamic broadast");
11331            }
11332            mReceiverResolver.addFilter(bf);
11333
11334            // Enqueue broadcasts for all existing stickies that match
11335            // this filter.
11336            if (allSticky != null) {
11337                ArrayList receivers = new ArrayList();
11338                receivers.add(bf);
11339
11340                int N = allSticky.size();
11341                for (int i=0; i<N; i++) {
11342                    Intent intent = (Intent)allSticky.get(i);
11343                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11344                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11345                            null, -1, -1, null, receivers, null, 0, null, null,
11346                            false, true, true, -1);
11347                    queue.enqueueParallelBroadcastLocked(r);
11348                    queue.scheduleBroadcastsLocked();
11349                }
11350            }
11351
11352            return sticky;
11353        }
11354    }
11355
11356    public void unregisterReceiver(IIntentReceiver receiver) {
11357        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11358
11359        final long origId = Binder.clearCallingIdentity();
11360        try {
11361            boolean doTrim = false;
11362
11363            synchronized(this) {
11364                ReceiverList rl
11365                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11366                if (rl != null) {
11367                    if (rl.curBroadcast != null) {
11368                        BroadcastRecord r = rl.curBroadcast;
11369                        final boolean doNext = finishReceiverLocked(
11370                                receiver.asBinder(), r.resultCode, r.resultData,
11371                                r.resultExtras, r.resultAbort, true);
11372                        if (doNext) {
11373                            doTrim = true;
11374                            r.queue.processNextBroadcast(false);
11375                        }
11376                    }
11377
11378                    if (rl.app != null) {
11379                        rl.app.receivers.remove(rl);
11380                    }
11381                    removeReceiverLocked(rl);
11382                    if (rl.linkedToDeath) {
11383                        rl.linkedToDeath = false;
11384                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11385                    }
11386                }
11387            }
11388
11389            // If we actually concluded any broadcasts, we might now be able
11390            // to trim the recipients' apps from our working set
11391            if (doTrim) {
11392                trimApplications();
11393                return;
11394            }
11395
11396        } finally {
11397            Binder.restoreCallingIdentity(origId);
11398        }
11399    }
11400
11401    void removeReceiverLocked(ReceiverList rl) {
11402        mRegisteredReceivers.remove(rl.receiver.asBinder());
11403        int N = rl.size();
11404        for (int i=0; i<N; i++) {
11405            mReceiverResolver.removeFilter(rl.get(i));
11406        }
11407    }
11408
11409    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11410        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11411            ProcessRecord r = mLruProcesses.get(i);
11412            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11413                try {
11414                    r.thread.dispatchPackageBroadcast(cmd, packages);
11415                } catch (RemoteException ex) {
11416                }
11417            }
11418        }
11419    }
11420
11421    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11422            int[] users) {
11423        List<ResolveInfo> receivers = null;
11424        try {
11425            HashSet<ComponentName> singleUserReceivers = null;
11426            boolean scannedFirstReceivers = false;
11427            for (int user : users) {
11428                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11429                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11430                if (newReceivers != null && newReceivers.size() == 0) {
11431                    newReceivers = null;
11432                }
11433                if (receivers == null) {
11434                    receivers = newReceivers;
11435                } else if (newReceivers != null) {
11436                    // We need to concatenate the additional receivers
11437                    // found with what we have do far.  This would be easy,
11438                    // but we also need to de-dup any receivers that are
11439                    // singleUser.
11440                    if (!scannedFirstReceivers) {
11441                        // Collect any single user receivers we had already retrieved.
11442                        scannedFirstReceivers = true;
11443                        for (int i=0; i<receivers.size(); i++) {
11444                            ResolveInfo ri = receivers.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                                singleUserReceivers.add(cn);
11452                            }
11453                        }
11454                    }
11455                    // Add the new results to the existing results, tracking
11456                    // and de-dupping single user receivers.
11457                    for (int i=0; i<newReceivers.size(); i++) {
11458                        ResolveInfo ri = newReceivers.get(i);
11459                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11460                            ComponentName cn = new ComponentName(
11461                                    ri.activityInfo.packageName, ri.activityInfo.name);
11462                            if (singleUserReceivers == null) {
11463                                singleUserReceivers = new HashSet<ComponentName>();
11464                            }
11465                            if (!singleUserReceivers.contains(cn)) {
11466                                singleUserReceivers.add(cn);
11467                                receivers.add(ri);
11468                            }
11469                        } else {
11470                            receivers.add(ri);
11471                        }
11472                    }
11473                }
11474            }
11475        } catch (RemoteException ex) {
11476            // pm is in same process, this will never happen.
11477        }
11478        return receivers;
11479    }
11480
11481    private final int broadcastIntentLocked(ProcessRecord callerApp,
11482            String callerPackage, Intent intent, String resolvedType,
11483            IIntentReceiver resultTo, int resultCode, String resultData,
11484            Bundle map, String requiredPermission,
11485            boolean ordered, boolean sticky, int callingPid, int callingUid,
11486            int userId) {
11487        intent = new Intent(intent);
11488
11489        // By default broadcasts do not go to stopped apps.
11490        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11491
11492        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11493            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11494            + " ordered=" + ordered + " userid=" + userId);
11495        if ((resultTo != null) && !ordered) {
11496            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11497        }
11498
11499        userId = handleIncomingUser(callingPid, callingUid, userId,
11500                true, false, "broadcast", callerPackage);
11501
11502        // Make sure that the user who is receiving this broadcast is started.
11503        // If not, we will just skip it.
11504        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11505            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11506                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11507                Slog.w(TAG, "Skipping broadcast of " + intent
11508                        + ": user " + userId + " is stopped");
11509                return ActivityManager.BROADCAST_SUCCESS;
11510            }
11511        }
11512
11513        /*
11514         * Prevent non-system code (defined here to be non-persistent
11515         * processes) from sending protected broadcasts.
11516         */
11517        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11518            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11519            callingUid == 0) {
11520            // Always okay.
11521        } else if (callerApp == null || !callerApp.persistent) {
11522            try {
11523                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11524                        intent.getAction())) {
11525                    String msg = "Permission Denial: not allowed to send broadcast "
11526                            + intent.getAction() + " from pid="
11527                            + callingPid + ", uid=" + callingUid;
11528                    Slog.w(TAG, msg);
11529                    throw new SecurityException(msg);
11530                }
11531            } catch (RemoteException e) {
11532                Slog.w(TAG, "Remote exception", e);
11533                return ActivityManager.BROADCAST_SUCCESS;
11534            }
11535        }
11536
11537        // Handle special intents: if this broadcast is from the package
11538        // manager about a package being removed, we need to remove all of
11539        // its activities from the history stack.
11540        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11541                intent.getAction());
11542        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11543                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11544                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11545                || uidRemoved) {
11546            if (checkComponentPermission(
11547                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11548                    callingPid, callingUid, -1, true)
11549                    == PackageManager.PERMISSION_GRANTED) {
11550                if (uidRemoved) {
11551                    final Bundle intentExtras = intent.getExtras();
11552                    final int uid = intentExtras != null
11553                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11554                    if (uid >= 0) {
11555                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11556                        synchronized (bs) {
11557                            bs.removeUidStatsLocked(uid);
11558                        }
11559                    }
11560                } else {
11561                    // If resources are unavailable just force stop all
11562                    // those packages and flush the attribute cache as well.
11563                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11564                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11565                        if (list != null && (list.length > 0)) {
11566                            for (String pkg : list) {
11567                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11568                            }
11569                            sendPackageBroadcastLocked(
11570                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11571                        }
11572                    } else {
11573                        Uri data = intent.getData();
11574                        String ssp;
11575                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11576                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11577                                forceStopPackageLocked(ssp,
11578                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11579                                        false, userId);
11580                            }
11581                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11582                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11583                                        new String[] {ssp}, userId);
11584                            }
11585                        }
11586                    }
11587                }
11588            } else {
11589                String msg = "Permission Denial: " + intent.getAction()
11590                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11591                        + ", uid=" + callingUid + ")"
11592                        + " requires "
11593                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11594                Slog.w(TAG, msg);
11595                throw new SecurityException(msg);
11596            }
11597
11598        // Special case for adding a package: by default turn on compatibility
11599        // mode.
11600        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11601            Uri data = intent.getData();
11602            String ssp;
11603            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11604                mCompatModePackages.handlePackageAddedLocked(ssp,
11605                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11606            }
11607        }
11608
11609        /*
11610         * If this is the time zone changed action, queue up a message that will reset the timezone
11611         * of all currently running processes. This message will get queued up before the broadcast
11612         * happens.
11613         */
11614        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11615            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11616        }
11617
11618        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11619            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11620        }
11621
11622        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11623            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11624            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11625        }
11626
11627        // Add to the sticky list if requested.
11628        if (sticky) {
11629            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11630                    callingPid, callingUid)
11631                    != PackageManager.PERMISSION_GRANTED) {
11632                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11633                        + callingPid + ", uid=" + callingUid
11634                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11635                Slog.w(TAG, msg);
11636                throw new SecurityException(msg);
11637            }
11638            if (requiredPermission != null) {
11639                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11640                        + " and enforce permission " + requiredPermission);
11641                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11642            }
11643            if (intent.getComponent() != null) {
11644                throw new SecurityException(
11645                        "Sticky broadcasts can't target a specific component");
11646            }
11647            // We use userId directly here, since the "all" target is maintained
11648            // as a separate set of sticky broadcasts.
11649            if (userId != UserHandle.USER_ALL) {
11650                // But first, if this is not a broadcast to all users, then
11651                // make sure it doesn't conflict with an existing broadcast to
11652                // all users.
11653                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11654                        UserHandle.USER_ALL);
11655                if (stickies != null) {
11656                    ArrayList<Intent> list = stickies.get(intent.getAction());
11657                    if (list != null) {
11658                        int N = list.size();
11659                        int i;
11660                        for (i=0; i<N; i++) {
11661                            if (intent.filterEquals(list.get(i))) {
11662                                throw new IllegalArgumentException(
11663                                        "Sticky broadcast " + intent + " for user "
11664                                        + userId + " conflicts with existing global broadcast");
11665                            }
11666                        }
11667                    }
11668                }
11669            }
11670            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11671            if (stickies == null) {
11672                stickies = new HashMap<String, ArrayList<Intent>>();
11673                mStickyBroadcasts.put(userId, stickies);
11674            }
11675            ArrayList<Intent> list = stickies.get(intent.getAction());
11676            if (list == null) {
11677                list = new ArrayList<Intent>();
11678                stickies.put(intent.getAction(), list);
11679            }
11680            int N = list.size();
11681            int i;
11682            for (i=0; i<N; i++) {
11683                if (intent.filterEquals(list.get(i))) {
11684                    // This sticky already exists, replace it.
11685                    list.set(i, new Intent(intent));
11686                    break;
11687                }
11688            }
11689            if (i >= N) {
11690                list.add(new Intent(intent));
11691            }
11692        }
11693
11694        int[] users;
11695        if (userId == UserHandle.USER_ALL) {
11696            // Caller wants broadcast to go to all started users.
11697            users = mStartedUserArray;
11698        } else {
11699            // Caller wants broadcast to go to one specific user.
11700            users = mCurrentUserArray;
11701        }
11702
11703        // Figure out who all will receive this broadcast.
11704        List receivers = null;
11705        List<BroadcastFilter> registeredReceivers = null;
11706        // Need to resolve the intent to interested receivers...
11707        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11708                 == 0) {
11709            receivers = collectReceiverComponents(intent, resolvedType, users);
11710        }
11711        if (intent.getComponent() == null) {
11712            registeredReceivers = mReceiverResolver.queryIntent(intent,
11713                    resolvedType, false, userId);
11714        }
11715
11716        final boolean replacePending =
11717                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11718
11719        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11720                + " replacePending=" + replacePending);
11721
11722        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11723        if (!ordered && NR > 0) {
11724            // If we are not serializing this broadcast, then send the
11725            // registered receivers separately so they don't wait for the
11726            // components to be launched.
11727            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11728            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11729                    callerPackage, callingPid, callingUid, requiredPermission,
11730                    registeredReceivers, resultTo, resultCode, resultData, map,
11731                    ordered, sticky, false, userId);
11732            if (DEBUG_BROADCAST) Slog.v(
11733                    TAG, "Enqueueing parallel broadcast " + r);
11734            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11735            if (!replaced) {
11736                queue.enqueueParallelBroadcastLocked(r);
11737                queue.scheduleBroadcastsLocked();
11738            }
11739            registeredReceivers = null;
11740            NR = 0;
11741        }
11742
11743        // Merge into one list.
11744        int ir = 0;
11745        if (receivers != null) {
11746            // A special case for PACKAGE_ADDED: do not allow the package
11747            // being added to see this broadcast.  This prevents them from
11748            // using this as a back door to get run as soon as they are
11749            // installed.  Maybe in the future we want to have a special install
11750            // broadcast or such for apps, but we'd like to deliberately make
11751            // this decision.
11752            String skipPackages[] = null;
11753            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11754                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11755                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11756                Uri data = intent.getData();
11757                if (data != null) {
11758                    String pkgName = data.getSchemeSpecificPart();
11759                    if (pkgName != null) {
11760                        skipPackages = new String[] { pkgName };
11761                    }
11762                }
11763            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11764                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11765            }
11766            if (skipPackages != null && (skipPackages.length > 0)) {
11767                for (String skipPackage : skipPackages) {
11768                    if (skipPackage != null) {
11769                        int NT = receivers.size();
11770                        for (int it=0; it<NT; it++) {
11771                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11772                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11773                                receivers.remove(it);
11774                                it--;
11775                                NT--;
11776                            }
11777                        }
11778                    }
11779                }
11780            }
11781
11782            int NT = receivers != null ? receivers.size() : 0;
11783            int it = 0;
11784            ResolveInfo curt = null;
11785            BroadcastFilter curr = null;
11786            while (it < NT && ir < NR) {
11787                if (curt == null) {
11788                    curt = (ResolveInfo)receivers.get(it);
11789                }
11790                if (curr == null) {
11791                    curr = registeredReceivers.get(ir);
11792                }
11793                if (curr.getPriority() >= curt.priority) {
11794                    // Insert this broadcast record into the final list.
11795                    receivers.add(it, curr);
11796                    ir++;
11797                    curr = null;
11798                    it++;
11799                    NT++;
11800                } else {
11801                    // Skip to the next ResolveInfo in the final list.
11802                    it++;
11803                    curt = null;
11804                }
11805            }
11806        }
11807        while (ir < NR) {
11808            if (receivers == null) {
11809                receivers = new ArrayList();
11810            }
11811            receivers.add(registeredReceivers.get(ir));
11812            ir++;
11813        }
11814
11815        if ((receivers != null && receivers.size() > 0)
11816                || resultTo != null) {
11817            BroadcastQueue queue = broadcastQueueForIntent(intent);
11818            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11819                    callerPackage, callingPid, callingUid, requiredPermission,
11820                    receivers, resultTo, resultCode, resultData, map, ordered,
11821                    sticky, false, userId);
11822            if (DEBUG_BROADCAST) Slog.v(
11823                    TAG, "Enqueueing ordered broadcast " + r
11824                    + ": prev had " + queue.mOrderedBroadcasts.size());
11825            if (DEBUG_BROADCAST) {
11826                int seq = r.intent.getIntExtra("seq", -1);
11827                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11828            }
11829            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11830            if (!replaced) {
11831                queue.enqueueOrderedBroadcastLocked(r);
11832                queue.scheduleBroadcastsLocked();
11833            }
11834        }
11835
11836        return ActivityManager.BROADCAST_SUCCESS;
11837    }
11838
11839    final Intent verifyBroadcastLocked(Intent intent) {
11840        // Refuse possible leaked file descriptors
11841        if (intent != null && intent.hasFileDescriptors() == true) {
11842            throw new IllegalArgumentException("File descriptors passed in Intent");
11843        }
11844
11845        int flags = intent.getFlags();
11846
11847        if (!mProcessesReady) {
11848            // if the caller really truly claims to know what they're doing, go
11849            // ahead and allow the broadcast without launching any receivers
11850            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11851                intent = new Intent(intent);
11852                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11853            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11854                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11855                        + " before boot completion");
11856                throw new IllegalStateException("Cannot broadcast before boot completed");
11857            }
11858        }
11859
11860        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11861            throw new IllegalArgumentException(
11862                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11863        }
11864
11865        return intent;
11866    }
11867
11868    public final int broadcastIntent(IApplicationThread caller,
11869            Intent intent, String resolvedType, IIntentReceiver resultTo,
11870            int resultCode, String resultData, Bundle map,
11871            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11872        enforceNotIsolatedCaller("broadcastIntent");
11873        synchronized(this) {
11874            intent = verifyBroadcastLocked(intent);
11875
11876            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11877            final int callingPid = Binder.getCallingPid();
11878            final int callingUid = Binder.getCallingUid();
11879            final long origId = Binder.clearCallingIdentity();
11880            int res = broadcastIntentLocked(callerApp,
11881                    callerApp != null ? callerApp.info.packageName : null,
11882                    intent, resolvedType, resultTo,
11883                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11884                    callingPid, callingUid, userId);
11885            Binder.restoreCallingIdentity(origId);
11886            return res;
11887        }
11888    }
11889
11890    int broadcastIntentInPackage(String packageName, int uid,
11891            Intent intent, String resolvedType, IIntentReceiver resultTo,
11892            int resultCode, String resultData, Bundle map,
11893            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11894        synchronized(this) {
11895            intent = verifyBroadcastLocked(intent);
11896
11897            final long origId = Binder.clearCallingIdentity();
11898            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11899                    resultTo, resultCode, resultData, map, requiredPermission,
11900                    serialized, sticky, -1, uid, userId);
11901            Binder.restoreCallingIdentity(origId);
11902            return res;
11903        }
11904    }
11905
11906    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11907        // Refuse possible leaked file descriptors
11908        if (intent != null && intent.hasFileDescriptors() == true) {
11909            throw new IllegalArgumentException("File descriptors passed in Intent");
11910        }
11911
11912        userId = handleIncomingUser(Binder.getCallingPid(),
11913                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11914
11915        synchronized(this) {
11916            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11917                    != PackageManager.PERMISSION_GRANTED) {
11918                String msg = "Permission Denial: unbroadcastIntent() from pid="
11919                        + Binder.getCallingPid()
11920                        + ", uid=" + Binder.getCallingUid()
11921                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11922                Slog.w(TAG, msg);
11923                throw new SecurityException(msg);
11924            }
11925            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11926            if (stickies != null) {
11927                ArrayList<Intent> list = stickies.get(intent.getAction());
11928                if (list != null) {
11929                    int N = list.size();
11930                    int i;
11931                    for (i=0; i<N; i++) {
11932                        if (intent.filterEquals(list.get(i))) {
11933                            list.remove(i);
11934                            break;
11935                        }
11936                    }
11937                    if (list.size() <= 0) {
11938                        stickies.remove(intent.getAction());
11939                    }
11940                }
11941                if (stickies.size() <= 0) {
11942                    mStickyBroadcasts.remove(userId);
11943                }
11944            }
11945        }
11946    }
11947
11948    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11949            String resultData, Bundle resultExtras, boolean resultAbort,
11950            boolean explicit) {
11951        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11952        if (r == null) {
11953            Slog.w(TAG, "finishReceiver called but not found on queue");
11954            return false;
11955        }
11956
11957        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11958                explicit);
11959    }
11960
11961    public void finishReceiver(IBinder who, int resultCode, String resultData,
11962            Bundle resultExtras, boolean resultAbort) {
11963        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11964
11965        // Refuse possible leaked file descriptors
11966        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11967            throw new IllegalArgumentException("File descriptors passed in Bundle");
11968        }
11969
11970        final long origId = Binder.clearCallingIdentity();
11971        try {
11972            boolean doNext = false;
11973            BroadcastRecord r = null;
11974
11975            synchronized(this) {
11976                r = broadcastRecordForReceiverLocked(who);
11977                if (r != null) {
11978                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11979                        resultData, resultExtras, resultAbort, true);
11980                }
11981            }
11982
11983            if (doNext) {
11984                r.queue.processNextBroadcast(false);
11985            }
11986            trimApplications();
11987        } finally {
11988            Binder.restoreCallingIdentity(origId);
11989        }
11990    }
11991
11992    // =========================================================
11993    // INSTRUMENTATION
11994    // =========================================================
11995
11996    public boolean startInstrumentation(ComponentName className,
11997            String profileFile, int flags, Bundle arguments,
11998            IInstrumentationWatcher watcher, int userId) {
11999        enforceNotIsolatedCaller("startInstrumentation");
12000        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12001                userId, false, true, "startInstrumentation", null);
12002        // Refuse possible leaked file descriptors
12003        if (arguments != null && arguments.hasFileDescriptors()) {
12004            throw new IllegalArgumentException("File descriptors passed in Bundle");
12005        }
12006
12007        synchronized(this) {
12008            InstrumentationInfo ii = null;
12009            ApplicationInfo ai = null;
12010            try {
12011                ii = mContext.getPackageManager().getInstrumentationInfo(
12012                    className, STOCK_PM_FLAGS);
12013                ai = AppGlobals.getPackageManager().getApplicationInfo(
12014                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12015            } catch (PackageManager.NameNotFoundException e) {
12016            } catch (RemoteException e) {
12017            }
12018            if (ii == null) {
12019                reportStartInstrumentationFailure(watcher, className,
12020                        "Unable to find instrumentation info for: " + className);
12021                return false;
12022            }
12023            if (ai == null) {
12024                reportStartInstrumentationFailure(watcher, className,
12025                        "Unable to find instrumentation target package: " + ii.targetPackage);
12026                return false;
12027            }
12028
12029            int match = mContext.getPackageManager().checkSignatures(
12030                    ii.targetPackage, ii.packageName);
12031            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12032                String msg = "Permission Denial: starting instrumentation "
12033                        + className + " from pid="
12034                        + Binder.getCallingPid()
12035                        + ", uid=" + Binder.getCallingPid()
12036                        + " not allowed because package " + ii.packageName
12037                        + " does not have a signature matching the target "
12038                        + ii.targetPackage;
12039                reportStartInstrumentationFailure(watcher, className, msg);
12040                throw new SecurityException(msg);
12041            }
12042
12043            final long origId = Binder.clearCallingIdentity();
12044            // Instrumentation can kill and relaunch even persistent processes
12045            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12046            ProcessRecord app = addAppLocked(ai, false);
12047            app.instrumentationClass = className;
12048            app.instrumentationInfo = ai;
12049            app.instrumentationProfileFile = profileFile;
12050            app.instrumentationArguments = arguments;
12051            app.instrumentationWatcher = watcher;
12052            app.instrumentationResultClass = className;
12053            Binder.restoreCallingIdentity(origId);
12054        }
12055
12056        return true;
12057    }
12058
12059    /**
12060     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12061     * error to the logs, but if somebody is watching, send the report there too.  This enables
12062     * the "am" command to report errors with more information.
12063     *
12064     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12065     * @param cn The component name of the instrumentation.
12066     * @param report The error report.
12067     */
12068    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12069            ComponentName cn, String report) {
12070        Slog.w(TAG, report);
12071        try {
12072            if (watcher != null) {
12073                Bundle results = new Bundle();
12074                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12075                results.putString("Error", report);
12076                watcher.instrumentationStatus(cn, -1, results);
12077            }
12078        } catch (RemoteException e) {
12079            Slog.w(TAG, e);
12080        }
12081    }
12082
12083    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12084        if (app.instrumentationWatcher != null) {
12085            try {
12086                // NOTE:  IInstrumentationWatcher *must* be oneway here
12087                app.instrumentationWatcher.instrumentationFinished(
12088                    app.instrumentationClass,
12089                    resultCode,
12090                    results);
12091            } catch (RemoteException e) {
12092            }
12093        }
12094        app.instrumentationWatcher = null;
12095        app.instrumentationClass = null;
12096        app.instrumentationInfo = null;
12097        app.instrumentationProfileFile = null;
12098        app.instrumentationArguments = null;
12099
12100        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12101    }
12102
12103    public void finishInstrumentation(IApplicationThread target,
12104            int resultCode, Bundle results) {
12105        int userId = UserHandle.getCallingUserId();
12106        // Refuse possible leaked file descriptors
12107        if (results != null && results.hasFileDescriptors()) {
12108            throw new IllegalArgumentException("File descriptors passed in Intent");
12109        }
12110
12111        synchronized(this) {
12112            ProcessRecord app = getRecordForAppLocked(target);
12113            if (app == null) {
12114                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12115                return;
12116            }
12117            final long origId = Binder.clearCallingIdentity();
12118            finishInstrumentationLocked(app, resultCode, results);
12119            Binder.restoreCallingIdentity(origId);
12120        }
12121    }
12122
12123    // =========================================================
12124    // CONFIGURATION
12125    // =========================================================
12126
12127    public ConfigurationInfo getDeviceConfigurationInfo() {
12128        ConfigurationInfo config = new ConfigurationInfo();
12129        synchronized (this) {
12130            config.reqTouchScreen = mConfiguration.touchscreen;
12131            config.reqKeyboardType = mConfiguration.keyboard;
12132            config.reqNavigation = mConfiguration.navigation;
12133            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12134                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12135                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12136            }
12137            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12138                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12139                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12140            }
12141            config.reqGlEsVersion = GL_ES_VERSION;
12142        }
12143        return config;
12144    }
12145
12146    public Configuration getConfiguration() {
12147        Configuration ci;
12148        synchronized(this) {
12149            ci = new Configuration(mConfiguration);
12150        }
12151        return ci;
12152    }
12153
12154    public void updatePersistentConfiguration(Configuration values) {
12155        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12156                "updateConfiguration()");
12157        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12158                "updateConfiguration()");
12159        if (values == null) {
12160            throw new NullPointerException("Configuration must not be null");
12161        }
12162
12163        synchronized(this) {
12164            final long origId = Binder.clearCallingIdentity();
12165            updateConfigurationLocked(values, null, true, false);
12166            Binder.restoreCallingIdentity(origId);
12167        }
12168    }
12169
12170    public void updateConfiguration(Configuration values) {
12171        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12172                "updateConfiguration()");
12173
12174        synchronized(this) {
12175            if (values == null && mWindowManager != null) {
12176                // sentinel: fetch the current configuration from the window manager
12177                values = mWindowManager.computeNewConfiguration();
12178            }
12179
12180            if (mWindowManager != null) {
12181                mProcessList.applyDisplaySize(mWindowManager);
12182            }
12183
12184            final long origId = Binder.clearCallingIdentity();
12185            if (values != null) {
12186                Settings.System.clearConfiguration(values);
12187            }
12188            updateConfigurationLocked(values, null, false, false);
12189            Binder.restoreCallingIdentity(origId);
12190        }
12191    }
12192
12193    /**
12194     * Do either or both things: (1) change the current configuration, and (2)
12195     * make sure the given activity is running with the (now) current
12196     * configuration.  Returns true if the activity has been left running, or
12197     * false if <var>starting</var> is being destroyed to match the new
12198     * configuration.
12199     * @param persistent TODO
12200     */
12201    boolean updateConfigurationLocked(Configuration values,
12202            ActivityRecord starting, boolean persistent, boolean initLocale) {
12203        // do nothing if we are headless
12204        if (mHeadless) return true;
12205
12206        int changes = 0;
12207
12208        boolean kept = true;
12209
12210        if (values != null) {
12211            Configuration newConfig = new Configuration(mConfiguration);
12212            changes = newConfig.updateFrom(values);
12213            if (changes != 0) {
12214                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12215                    Slog.i(TAG, "Updating configuration to: " + values);
12216                }
12217
12218                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12219
12220                if (values.locale != null && !initLocale) {
12221                    saveLocaleLocked(values.locale,
12222                                     !values.locale.equals(mConfiguration.locale),
12223                                     values.userSetLocale);
12224                }
12225
12226                mConfigurationSeq++;
12227                if (mConfigurationSeq <= 0) {
12228                    mConfigurationSeq = 1;
12229                }
12230                newConfig.seq = mConfigurationSeq;
12231                mConfiguration = newConfig;
12232                Slog.i(TAG, "Config changed: " + newConfig);
12233
12234                final Configuration configCopy = new Configuration(mConfiguration);
12235
12236                // TODO: If our config changes, should we auto dismiss any currently
12237                // showing dialogs?
12238                mShowDialogs = shouldShowDialogs(newConfig);
12239
12240                AttributeCache ac = AttributeCache.instance();
12241                if (ac != null) {
12242                    ac.updateConfiguration(configCopy);
12243                }
12244
12245                // Make sure all resources in our process are updated
12246                // right now, so that anyone who is going to retrieve
12247                // resource values after we return will be sure to get
12248                // the new ones.  This is especially important during
12249                // boot, where the first config change needs to guarantee
12250                // all resources have that config before following boot
12251                // code is executed.
12252                mSystemThread.applyConfigurationToResources(configCopy);
12253
12254                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12255                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12256                    msg.obj = new Configuration(configCopy);
12257                    mHandler.sendMessage(msg);
12258                }
12259
12260                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12261                    ProcessRecord app = mLruProcesses.get(i);
12262                    try {
12263                        if (app.thread != null) {
12264                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12265                                    + app.processName + " new config " + mConfiguration);
12266                            app.thread.scheduleConfigurationChanged(configCopy);
12267                        }
12268                    } catch (Exception e) {
12269                    }
12270                }
12271                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12272                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12273                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12274                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12275                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12276                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12277                    broadcastIntentLocked(null, null,
12278                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12279                            null, null, 0, null, null,
12280                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12281                }
12282            }
12283        }
12284
12285        if (changes != 0 && starting == null) {
12286            // If the configuration changed, and the caller is not already
12287            // in the process of starting an activity, then find the top
12288            // activity to check if its configuration needs to change.
12289            starting = mMainStack.topRunningActivityLocked(null);
12290        }
12291
12292        if (starting != null) {
12293            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12294            // And we need to make sure at this point that all other activities
12295            // are made visible with the correct configuration.
12296            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12297        }
12298
12299        if (values != null && mWindowManager != null) {
12300            mWindowManager.setNewConfiguration(mConfiguration);
12301        }
12302
12303        return kept;
12304    }
12305
12306    /**
12307     * Decide based on the configuration whether we should shouw the ANR,
12308     * crash, etc dialogs.  The idea is that if there is no affordnace to
12309     * press the on-screen buttons, we shouldn't show the dialog.
12310     *
12311     * A thought: SystemUI might also want to get told about this, the Power
12312     * dialog / global actions also might want different behaviors.
12313     */
12314    private static final boolean shouldShowDialogs(Configuration config) {
12315        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12316                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12317    }
12318
12319    /**
12320     * Save the locale.  You must be inside a synchronized (this) block.
12321     */
12322    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12323        if(isDiff) {
12324            SystemProperties.set("user.language", l.getLanguage());
12325            SystemProperties.set("user.region", l.getCountry());
12326        }
12327
12328        if(isPersist) {
12329            SystemProperties.set("persist.sys.language", l.getLanguage());
12330            SystemProperties.set("persist.sys.country", l.getCountry());
12331            SystemProperties.set("persist.sys.localevar", l.getVariant());
12332        }
12333    }
12334
12335    @Override
12336    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12337        ActivityRecord srec = ActivityRecord.forToken(token);
12338        return srec != null && srec.task.affinity != null &&
12339                srec.task.affinity.equals(destAffinity);
12340    }
12341
12342    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12343            Intent resultData) {
12344        ComponentName dest = destIntent.getComponent();
12345
12346        synchronized (this) {
12347            ActivityRecord srec = ActivityRecord.forToken(token);
12348            if (srec == null) {
12349                return false;
12350            }
12351            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12352            final int start = history.indexOf(srec);
12353            if (start < 0) {
12354                // Current activity is not in history stack; do nothing.
12355                return false;
12356            }
12357            int finishTo = start - 1;
12358            ActivityRecord parent = null;
12359            boolean foundParentInTask = false;
12360            if (dest != null) {
12361                TaskRecord tr = srec.task;
12362                for (int i = start - 1; i >= 0; i--) {
12363                    ActivityRecord r = history.get(i);
12364                    if (tr != r.task) {
12365                        // Couldn't find parent in the same task; stop at the one above this.
12366                        // (Root of current task; in-app "home" behavior)
12367                        // Always at least finish the current activity.
12368                        finishTo = Math.min(start - 1, i + 1);
12369                        parent = history.get(finishTo);
12370                        break;
12371                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12372                            r.info.name.equals(dest.getClassName())) {
12373                        finishTo = i;
12374                        parent = r;
12375                        foundParentInTask = true;
12376                        break;
12377                    }
12378                }
12379            }
12380
12381            if (mController != null) {
12382                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12383                if (next != null) {
12384                    // ask watcher if this is allowed
12385                    boolean resumeOK = true;
12386                    try {
12387                        resumeOK = mController.activityResuming(next.packageName);
12388                    } catch (RemoteException e) {
12389                        mController = null;
12390                    }
12391
12392                    if (!resumeOK) {
12393                        return false;
12394                    }
12395                }
12396            }
12397            final long origId = Binder.clearCallingIdentity();
12398            for (int i = start; i > finishTo; i--) {
12399                ActivityRecord r = history.get(i);
12400                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12401                        "navigate-up", true);
12402                // Only return the supplied result for the first activity finished
12403                resultCode = Activity.RESULT_CANCELED;
12404                resultData = null;
12405            }
12406
12407            if (parent != null && foundParentInTask) {
12408                final int parentLaunchMode = parent.info.launchMode;
12409                final int destIntentFlags = destIntent.getFlags();
12410                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12411                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12412                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12413                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12414                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12415                } else {
12416                    try {
12417                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12418                                destIntent.getComponent(), 0, srec.userId);
12419                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12420                                null, aInfo, parent.appToken, null,
12421                                0, -1, parent.launchedFromUid, 0, null, true, null);
12422                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12423                    } catch (RemoteException e) {
12424                        foundParentInTask = false;
12425                    }
12426                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12427                            resultData, "navigate-up", true);
12428                }
12429            }
12430            Binder.restoreCallingIdentity(origId);
12431            return foundParentInTask;
12432        }
12433    }
12434
12435    public int getLaunchedFromUid(IBinder activityToken) {
12436        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12437        if (srec == null) {
12438            return -1;
12439        }
12440        return srec.launchedFromUid;
12441    }
12442
12443    // =========================================================
12444    // LIFETIME MANAGEMENT
12445    // =========================================================
12446
12447    // Returns which broadcast queue the app is the current [or imminent] receiver
12448    // on, or 'null' if the app is not an active broadcast recipient.
12449    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12450        BroadcastRecord r = app.curReceiver;
12451        if (r != null) {
12452            return r.queue;
12453        }
12454
12455        // It's not the current receiver, but it might be starting up to become one
12456        synchronized (this) {
12457            for (BroadcastQueue queue : mBroadcastQueues) {
12458                r = queue.mPendingBroadcast;
12459                if (r != null && r.curApp == app) {
12460                    // found it; report which queue it's in
12461                    return queue;
12462                }
12463            }
12464        }
12465
12466        return null;
12467    }
12468
12469    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12470            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12471        if (mAdjSeq == app.adjSeq) {
12472            // This adjustment has already been computed.  If we are calling
12473            // from the top, we may have already computed our adjustment with
12474            // an earlier hidden adjustment that isn't really for us... if
12475            // so, use the new hidden adjustment.
12476            if (!recursed && app.hidden) {
12477                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12478                        app.hasActivities ? hiddenAdj : emptyAdj;
12479            }
12480            return app.curRawAdj;
12481        }
12482
12483        if (app.thread == null) {
12484            app.adjSeq = mAdjSeq;
12485            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12486            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12487        }
12488
12489        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12490        app.adjSource = null;
12491        app.adjTarget = null;
12492        app.empty = false;
12493        app.hidden = false;
12494
12495        final int activitiesSize = app.activities.size();
12496
12497        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12498            // The max adjustment doesn't allow this app to be anything
12499            // below foreground, so it is not worth doing work for it.
12500            app.adjType = "fixed";
12501            app.adjSeq = mAdjSeq;
12502            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12503            app.hasActivities = false;
12504            app.foregroundActivities = false;
12505            app.keeping = true;
12506            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12507            // System process can do UI, and when they do we want to have
12508            // them trim their memory after the user leaves the UI.  To
12509            // facilitate this, here we need to determine whether or not it
12510            // is currently showing UI.
12511            app.systemNoUi = true;
12512            if (app == TOP_APP) {
12513                app.systemNoUi = false;
12514                app.hasActivities = true;
12515            } else if (activitiesSize > 0) {
12516                for (int j = 0; j < activitiesSize; j++) {
12517                    final ActivityRecord r = app.activities.get(j);
12518                    if (r.visible) {
12519                        app.systemNoUi = false;
12520                    }
12521                    if (r.app == app) {
12522                        app.hasActivities = true;
12523                    }
12524                }
12525            }
12526            return (app.curAdj=app.maxAdj);
12527        }
12528
12529        app.keeping = false;
12530        app.systemNoUi = false;
12531        app.hasActivities = false;
12532
12533        // Determine the importance of the process, starting with most
12534        // important to least, and assign an appropriate OOM adjustment.
12535        int adj;
12536        int schedGroup;
12537        boolean foregroundActivities = false;
12538        boolean interesting = false;
12539        BroadcastQueue queue;
12540        if (app == TOP_APP) {
12541            // The last app on the list is the foreground app.
12542            adj = ProcessList.FOREGROUND_APP_ADJ;
12543            schedGroup = Process.THREAD_GROUP_DEFAULT;
12544            app.adjType = "top-activity";
12545            foregroundActivities = true;
12546            interesting = true;
12547            app.hasActivities = true;
12548        } else if (app.instrumentationClass != null) {
12549            // Don't want to kill running instrumentation.
12550            adj = ProcessList.FOREGROUND_APP_ADJ;
12551            schedGroup = Process.THREAD_GROUP_DEFAULT;
12552            app.adjType = "instrumentation";
12553            interesting = true;
12554        } else if ((queue = isReceivingBroadcast(app)) != null) {
12555            // An app that is currently receiving a broadcast also
12556            // counts as being in the foreground for OOM killer purposes.
12557            // It's placed in a sched group based on the nature of the
12558            // broadcast as reflected by which queue it's active in.
12559            adj = ProcessList.FOREGROUND_APP_ADJ;
12560            schedGroup = (queue == mFgBroadcastQueue)
12561                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12562            app.adjType = "broadcast";
12563        } else if (app.executingServices.size() > 0) {
12564            // An app that is currently executing a service callback also
12565            // counts as being in the foreground.
12566            adj = ProcessList.FOREGROUND_APP_ADJ;
12567            schedGroup = Process.THREAD_GROUP_DEFAULT;
12568            app.adjType = "exec-service";
12569        } else {
12570            // Assume process is hidden (has activities); we will correct
12571            // later if this is not the case.
12572            adj = hiddenAdj;
12573            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12574            app.hidden = true;
12575            app.adjType = "bg-activities";
12576        }
12577
12578        boolean hasStoppingActivities = false;
12579
12580        // Examine all activities if not already foreground.
12581        if (!foregroundActivities && activitiesSize > 0) {
12582            for (int j = 0; j < activitiesSize; j++) {
12583                final ActivityRecord r = app.activities.get(j);
12584                if (r.visible) {
12585                    // App has a visible activity; only upgrade adjustment.
12586                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12587                        adj = ProcessList.VISIBLE_APP_ADJ;
12588                        app.adjType = "visible";
12589                    }
12590                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12591                    app.hidden = false;
12592                    app.hasActivities = true;
12593                    foregroundActivities = true;
12594                    break;
12595                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12596                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12597                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12598                        app.adjType = "pausing";
12599                    }
12600                    app.hidden = false;
12601                    foregroundActivities = true;
12602                } else if (r.state == ActivityState.STOPPING) {
12603                    // We will apply the actual adjustment later, because
12604                    // we want to allow this process to immediately go through
12605                    // any memory trimming that is in effect.
12606                    app.hidden = false;
12607                    foregroundActivities = true;
12608                    hasStoppingActivities = true;
12609                }
12610                if (r.app == app) {
12611                    app.hasActivities = true;
12612                }
12613            }
12614        }
12615
12616        if (adj == hiddenAdj && !app.hasActivities) {
12617            // Whoops, this process is completely empty as far as we know
12618            // at this point.
12619            adj = emptyAdj;
12620            app.empty = true;
12621            app.adjType = "bg-empty";
12622        }
12623
12624        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12625            if (app.foregroundServices) {
12626                // The user is aware of this app, so make it visible.
12627                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12628                app.hidden = false;
12629                app.adjType = "foreground-service";
12630                schedGroup = Process.THREAD_GROUP_DEFAULT;
12631            } else if (app.forcingToForeground != null) {
12632                // The user is aware of this app, so make it visible.
12633                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12634                app.hidden = false;
12635                app.adjType = "force-foreground";
12636                app.adjSource = app.forcingToForeground;
12637                schedGroup = Process.THREAD_GROUP_DEFAULT;
12638            }
12639        }
12640
12641        if (app.foregroundServices) {
12642            interesting = true;
12643        }
12644
12645        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12646            // We don't want to kill the current heavy-weight process.
12647            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12648            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12649            app.hidden = false;
12650            app.adjType = "heavy";
12651        }
12652
12653        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12654            // This process is hosting what we currently consider to be the
12655            // home app, so we don't want to let it go into the background.
12656            adj = ProcessList.HOME_APP_ADJ;
12657            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12658            app.hidden = false;
12659            app.adjType = "home";
12660        }
12661
12662        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12663                && app.activities.size() > 0) {
12664            // This was the previous process that showed UI to the user.
12665            // We want to try to keep it around more aggressively, to give
12666            // a good experience around switching between two apps.
12667            adj = ProcessList.PREVIOUS_APP_ADJ;
12668            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12669            app.hidden = false;
12670            app.adjType = "previous";
12671        }
12672
12673        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12674                + " reason=" + app.adjType);
12675
12676        // By default, we use the computed adjustment.  It may be changed if
12677        // there are applications dependent on our services or providers, but
12678        // this gives us a baseline and makes sure we don't get into an
12679        // infinite recursion.
12680        app.adjSeq = mAdjSeq;
12681        app.curRawAdj = app.nonStoppingAdj = adj;
12682
12683        if (mBackupTarget != null && app == mBackupTarget.app) {
12684            // If possible we want to avoid killing apps while they're being backed up
12685            if (adj > ProcessList.BACKUP_APP_ADJ) {
12686                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12687                adj = ProcessList.BACKUP_APP_ADJ;
12688                app.adjType = "backup";
12689                app.hidden = false;
12690            }
12691        }
12692
12693        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12694                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12695            final long now = SystemClock.uptimeMillis();
12696            // This process is more important if the top activity is
12697            // bound to the service.
12698            Iterator<ServiceRecord> jt = app.services.iterator();
12699            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12700                ServiceRecord s = jt.next();
12701                if (s.startRequested) {
12702                    if (app.hasShownUi && app != mHomeProcess) {
12703                        // If this process has shown some UI, let it immediately
12704                        // go to the LRU list because it may be pretty heavy with
12705                        // UI stuff.  We'll tag it with a label just to help
12706                        // debug and understand what is going on.
12707                        if (adj > ProcessList.SERVICE_ADJ) {
12708                            app.adjType = "started-bg-ui-services";
12709                        }
12710                    } else {
12711                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12712                            // This service has seen some activity within
12713                            // recent memory, so we will keep its process ahead
12714                            // of the background processes.
12715                            if (adj > ProcessList.SERVICE_ADJ) {
12716                                adj = ProcessList.SERVICE_ADJ;
12717                                app.adjType = "started-services";
12718                                app.hidden = false;
12719                            }
12720                        }
12721                        // If we have let the service slide into the background
12722                        // state, still have some text describing what it is doing
12723                        // even though the service no longer has an impact.
12724                        if (adj > ProcessList.SERVICE_ADJ) {
12725                            app.adjType = "started-bg-services";
12726                        }
12727                    }
12728                    // Don't kill this process because it is doing work; it
12729                    // has said it is doing work.
12730                    app.keeping = true;
12731                }
12732                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12733                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12734                    Iterator<ArrayList<ConnectionRecord>> kt
12735                            = s.connections.values().iterator();
12736                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12737                        ArrayList<ConnectionRecord> clist = kt.next();
12738                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12739                            // XXX should compute this based on the max of
12740                            // all connected clients.
12741                            ConnectionRecord cr = clist.get(i);
12742                            if (cr.binding.client == app) {
12743                                // Binding to ourself is not interesting.
12744                                continue;
12745                            }
12746                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12747                                ProcessRecord client = cr.binding.client;
12748                                int clientAdj = adj;
12749                                int myHiddenAdj = hiddenAdj;
12750                                if (myHiddenAdj > client.hiddenAdj) {
12751                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12752                                        myHiddenAdj = client.hiddenAdj;
12753                                    } else {
12754                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12755                                    }
12756                                }
12757                                int myEmptyAdj = emptyAdj;
12758                                if (myEmptyAdj > client.emptyAdj) {
12759                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12760                                        myEmptyAdj = client.emptyAdj;
12761                                    } else {
12762                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12763                                    }
12764                                }
12765                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12766                                        myEmptyAdj, TOP_APP, true, doingAll);
12767                                String adjType = null;
12768                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12769                                    // Not doing bind OOM management, so treat
12770                                    // this guy more like a started service.
12771                                    if (app.hasShownUi && app != mHomeProcess) {
12772                                        // If this process has shown some UI, let it immediately
12773                                        // go to the LRU list because it may be pretty heavy with
12774                                        // UI stuff.  We'll tag it with a label just to help
12775                                        // debug and understand what is going on.
12776                                        if (adj > clientAdj) {
12777                                            adjType = "bound-bg-ui-services";
12778                                        }
12779                                        app.hidden = false;
12780                                        clientAdj = adj;
12781                                    } else {
12782                                        if (now >= (s.lastActivity
12783                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12784                                            // This service has not seen activity within
12785                                            // recent memory, so allow it to drop to the
12786                                            // LRU list if there is no other reason to keep
12787                                            // it around.  We'll also tag it with a label just
12788                                            // to help debug and undertand what is going on.
12789                                            if (adj > clientAdj) {
12790                                                adjType = "bound-bg-services";
12791                                            }
12792                                            clientAdj = adj;
12793                                        }
12794                                    }
12795                                }
12796                                if (adj > clientAdj) {
12797                                    // If this process has recently shown UI, and
12798                                    // the process that is binding to it is less
12799                                    // important than being visible, then we don't
12800                                    // care about the binding as much as we care
12801                                    // about letting this process get into the LRU
12802                                    // list to be killed and restarted if needed for
12803                                    // memory.
12804                                    if (app.hasShownUi && app != mHomeProcess
12805                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12806                                        adjType = "bound-bg-ui-services";
12807                                    } else {
12808                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12809                                                |Context.BIND_IMPORTANT)) != 0) {
12810                                            adj = clientAdj;
12811                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12812                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12813                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12814                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12815                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12816                                            adj = clientAdj;
12817                                        } else {
12818                                            app.pendingUiClean = true;
12819                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12820                                                adj = ProcessList.VISIBLE_APP_ADJ;
12821                                            }
12822                                        }
12823                                        if (!client.hidden) {
12824                                            app.hidden = false;
12825                                        }
12826                                        if (client.keeping) {
12827                                            app.keeping = true;
12828                                        }
12829                                        adjType = "service";
12830                                    }
12831                                }
12832                                if (adjType != null) {
12833                                    app.adjType = adjType;
12834                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12835                                            .REASON_SERVICE_IN_USE;
12836                                    app.adjSource = cr.binding.client;
12837                                    app.adjSourceOom = clientAdj;
12838                                    app.adjTarget = s.name;
12839                                }
12840                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12841                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12842                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12843                                    }
12844                                }
12845                            }
12846                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12847                                ActivityRecord a = cr.activity;
12848                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12849                                        (a.visible || a.state == ActivityState.RESUMED
12850                                         || a.state == ActivityState.PAUSING)) {
12851                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12852                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12853                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12854                                    }
12855                                    app.hidden = false;
12856                                    app.adjType = "service";
12857                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12858                                            .REASON_SERVICE_IN_USE;
12859                                    app.adjSource = a;
12860                                    app.adjSourceOom = adj;
12861                                    app.adjTarget = s.name;
12862                                }
12863                            }
12864                        }
12865                    }
12866                }
12867            }
12868
12869            // Finally, if this process has active services running in it, we
12870            // would like to avoid killing it unless it would prevent the current
12871            // application from running.  By default we put the process in
12872            // with the rest of the background processes; as we scan through
12873            // its services we may bump it up from there.
12874            if (adj > hiddenAdj) {
12875                adj = hiddenAdj;
12876                app.hidden = false;
12877                app.adjType = "bg-services";
12878            }
12879        }
12880
12881        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12882                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12883            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12884            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12885                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12886                ContentProviderRecord cpr = jt.next();
12887                for (int i = cpr.connections.size()-1;
12888                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12889                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12890                        i--) {
12891                    ContentProviderConnection conn = cpr.connections.get(i);
12892                    ProcessRecord client = conn.client;
12893                    if (client == app) {
12894                        // Being our own client is not interesting.
12895                        continue;
12896                    }
12897                    int myHiddenAdj = hiddenAdj;
12898                    if (myHiddenAdj > client.hiddenAdj) {
12899                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12900                            myHiddenAdj = client.hiddenAdj;
12901                        } else {
12902                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12903                        }
12904                    }
12905                    int myEmptyAdj = emptyAdj;
12906                    if (myEmptyAdj > client.emptyAdj) {
12907                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12908                            myEmptyAdj = client.emptyAdj;
12909                        } else {
12910                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12911                        }
12912                    }
12913                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12914                            myEmptyAdj, TOP_APP, true, doingAll);
12915                    if (adj > clientAdj) {
12916                        if (app.hasShownUi && app != mHomeProcess
12917                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12918                            app.adjType = "bg-ui-provider";
12919                        } else {
12920                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12921                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12922                            app.adjType = "provider";
12923                        }
12924                        if (!client.hidden) {
12925                            app.hidden = false;
12926                        }
12927                        if (client.keeping) {
12928                            app.keeping = true;
12929                        }
12930                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12931                                .REASON_PROVIDER_IN_USE;
12932                        app.adjSource = client;
12933                        app.adjSourceOom = clientAdj;
12934                        app.adjTarget = cpr.name;
12935                    }
12936                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12937                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12938                    }
12939                }
12940                // If the provider has external (non-framework) process
12941                // dependencies, ensure that its adjustment is at least
12942                // FOREGROUND_APP_ADJ.
12943                if (cpr.hasExternalProcessHandles()) {
12944                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12945                        adj = ProcessList.FOREGROUND_APP_ADJ;
12946                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12947                        app.hidden = false;
12948                        app.keeping = true;
12949                        app.adjType = "provider";
12950                        app.adjTarget = cpr.name;
12951                    }
12952                }
12953            }
12954        }
12955
12956        if (adj == ProcessList.SERVICE_ADJ) {
12957            if (doingAll) {
12958                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12959                mNewNumServiceProcs++;
12960            }
12961            if (app.serviceb) {
12962                adj = ProcessList.SERVICE_B_ADJ;
12963            }
12964        } else {
12965            app.serviceb = false;
12966        }
12967
12968        app.nonStoppingAdj = adj;
12969
12970        if (hasStoppingActivities) {
12971            // Only upgrade adjustment.
12972            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12973                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12974                app.adjType = "stopping";
12975            }
12976        }
12977
12978        app.curRawAdj = adj;
12979
12980        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12981        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12982        if (adj > app.maxAdj) {
12983            adj = app.maxAdj;
12984            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12985                schedGroup = Process.THREAD_GROUP_DEFAULT;
12986            }
12987        }
12988        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12989            app.keeping = true;
12990        }
12991
12992        if (app.hasAboveClient) {
12993            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12994            // then we need to drop its adjustment to be lower than the service's
12995            // in order to honor the request.  We want to drop it by one adjustment
12996            // level...  but there is special meaning applied to various levels so
12997            // we will skip some of them.
12998            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12999                // System process will not get dropped, ever
13000            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13001                adj = ProcessList.VISIBLE_APP_ADJ;
13002            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13003                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13004            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13005                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13006            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13007                adj++;
13008            }
13009        }
13010
13011        int importance = app.memImportance;
13012        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13013            app.curAdj = adj;
13014            app.curSchedGroup = schedGroup;
13015            if (!interesting) {
13016                // For this reporting, if there is not something explicitly
13017                // interesting in this process then we will push it to the
13018                // background importance.
13019                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13020            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13021                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13022            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13023                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13024            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13025                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13026            } else if (adj >= ProcessList.SERVICE_ADJ) {
13027                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13028            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13029                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13030            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13031                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13032            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13033                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13034            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13035                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13036            } else {
13037                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13038            }
13039        }
13040
13041        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13042        if (foregroundActivities != app.foregroundActivities) {
13043            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13044        }
13045        if (changes != 0) {
13046            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13047            app.memImportance = importance;
13048            app.foregroundActivities = foregroundActivities;
13049            int i = mPendingProcessChanges.size()-1;
13050            ProcessChangeItem item = null;
13051            while (i >= 0) {
13052                item = mPendingProcessChanges.get(i);
13053                if (item.pid == app.pid) {
13054                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13055                    break;
13056                }
13057                i--;
13058            }
13059            if (i < 0) {
13060                // No existing item in pending changes; need a new one.
13061                final int NA = mAvailProcessChanges.size();
13062                if (NA > 0) {
13063                    item = mAvailProcessChanges.remove(NA-1);
13064                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13065                } else {
13066                    item = new ProcessChangeItem();
13067                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13068                }
13069                item.changes = 0;
13070                item.pid = app.pid;
13071                item.uid = app.info.uid;
13072                if (mPendingProcessChanges.size() == 0) {
13073                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13074                            "*** Enqueueing dispatch processes changed!");
13075                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13076                }
13077                mPendingProcessChanges.add(item);
13078            }
13079            item.changes |= changes;
13080            item.importance = importance;
13081            item.foregroundActivities = foregroundActivities;
13082            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13083                    + Integer.toHexString(System.identityHashCode(item))
13084                    + " " + app.toShortString() + ": changes=" + item.changes
13085                    + " importance=" + item.importance
13086                    + " foreground=" + item.foregroundActivities
13087                    + " type=" + app.adjType + " source=" + app.adjSource
13088                    + " target=" + app.adjTarget);
13089        }
13090
13091        return app.curRawAdj;
13092    }
13093
13094    /**
13095     * Ask a given process to GC right now.
13096     */
13097    final void performAppGcLocked(ProcessRecord app) {
13098        try {
13099            app.lastRequestedGc = SystemClock.uptimeMillis();
13100            if (app.thread != null) {
13101                if (app.reportLowMemory) {
13102                    app.reportLowMemory = false;
13103                    app.thread.scheduleLowMemory();
13104                } else {
13105                    app.thread.processInBackground();
13106                }
13107            }
13108        } catch (Exception e) {
13109            // whatever.
13110        }
13111    }
13112
13113    /**
13114     * Returns true if things are idle enough to perform GCs.
13115     */
13116    private final boolean canGcNowLocked() {
13117        boolean processingBroadcasts = false;
13118        for (BroadcastQueue q : mBroadcastQueues) {
13119            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13120                processingBroadcasts = true;
13121            }
13122        }
13123        return !processingBroadcasts
13124                && (mSleeping || (mMainStack.mResumedActivity != null &&
13125                        mMainStack.mResumedActivity.idle));
13126    }
13127
13128    /**
13129     * Perform GCs on all processes that are waiting for it, but only
13130     * if things are idle.
13131     */
13132    final void performAppGcsLocked() {
13133        final int N = mProcessesToGc.size();
13134        if (N <= 0) {
13135            return;
13136        }
13137        if (canGcNowLocked()) {
13138            while (mProcessesToGc.size() > 0) {
13139                ProcessRecord proc = mProcessesToGc.remove(0);
13140                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13141                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13142                            <= SystemClock.uptimeMillis()) {
13143                        // To avoid spamming the system, we will GC processes one
13144                        // at a time, waiting a few seconds between each.
13145                        performAppGcLocked(proc);
13146                        scheduleAppGcsLocked();
13147                        return;
13148                    } else {
13149                        // It hasn't been long enough since we last GCed this
13150                        // process...  put it in the list to wait for its time.
13151                        addProcessToGcListLocked(proc);
13152                        break;
13153                    }
13154                }
13155            }
13156
13157            scheduleAppGcsLocked();
13158        }
13159    }
13160
13161    /**
13162     * If all looks good, perform GCs on all processes waiting for them.
13163     */
13164    final void performAppGcsIfAppropriateLocked() {
13165        if (canGcNowLocked()) {
13166            performAppGcsLocked();
13167            return;
13168        }
13169        // Still not idle, wait some more.
13170        scheduleAppGcsLocked();
13171    }
13172
13173    /**
13174     * Schedule the execution of all pending app GCs.
13175     */
13176    final void scheduleAppGcsLocked() {
13177        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13178
13179        if (mProcessesToGc.size() > 0) {
13180            // Schedule a GC for the time to the next process.
13181            ProcessRecord proc = mProcessesToGc.get(0);
13182            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13183
13184            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13185            long now = SystemClock.uptimeMillis();
13186            if (when < (now+GC_TIMEOUT)) {
13187                when = now + GC_TIMEOUT;
13188            }
13189            mHandler.sendMessageAtTime(msg, when);
13190        }
13191    }
13192
13193    /**
13194     * Add a process to the array of processes waiting to be GCed.  Keeps the
13195     * list in sorted order by the last GC time.  The process can't already be
13196     * on the list.
13197     */
13198    final void addProcessToGcListLocked(ProcessRecord proc) {
13199        boolean added = false;
13200        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13201            if (mProcessesToGc.get(i).lastRequestedGc <
13202                    proc.lastRequestedGc) {
13203                added = true;
13204                mProcessesToGc.add(i+1, proc);
13205                break;
13206            }
13207        }
13208        if (!added) {
13209            mProcessesToGc.add(0, proc);
13210        }
13211    }
13212
13213    /**
13214     * Set up to ask a process to GC itself.  This will either do it
13215     * immediately, or put it on the list of processes to gc the next
13216     * time things are idle.
13217     */
13218    final void scheduleAppGcLocked(ProcessRecord app) {
13219        long now = SystemClock.uptimeMillis();
13220        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13221            return;
13222        }
13223        if (!mProcessesToGc.contains(app)) {
13224            addProcessToGcListLocked(app);
13225            scheduleAppGcsLocked();
13226        }
13227    }
13228
13229    final void checkExcessivePowerUsageLocked(boolean doKills) {
13230        updateCpuStatsNow();
13231
13232        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13233        boolean doWakeKills = doKills;
13234        boolean doCpuKills = doKills;
13235        if (mLastPowerCheckRealtime == 0) {
13236            doWakeKills = false;
13237        }
13238        if (mLastPowerCheckUptime == 0) {
13239            doCpuKills = false;
13240        }
13241        if (stats.isScreenOn()) {
13242            doWakeKills = false;
13243        }
13244        final long curRealtime = SystemClock.elapsedRealtime();
13245        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13246        final long curUptime = SystemClock.uptimeMillis();
13247        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13248        mLastPowerCheckRealtime = curRealtime;
13249        mLastPowerCheckUptime = curUptime;
13250        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13251            doWakeKills = false;
13252        }
13253        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13254            doCpuKills = false;
13255        }
13256        int i = mLruProcesses.size();
13257        while (i > 0) {
13258            i--;
13259            ProcessRecord app = mLruProcesses.get(i);
13260            if (!app.keeping) {
13261                long wtime;
13262                synchronized (stats) {
13263                    wtime = stats.getProcessWakeTime(app.info.uid,
13264                            app.pid, curRealtime);
13265                }
13266                long wtimeUsed = wtime - app.lastWakeTime;
13267                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13268                if (DEBUG_POWER) {
13269                    StringBuilder sb = new StringBuilder(128);
13270                    sb.append("Wake for ");
13271                    app.toShortString(sb);
13272                    sb.append(": over ");
13273                    TimeUtils.formatDuration(realtimeSince, sb);
13274                    sb.append(" used ");
13275                    TimeUtils.formatDuration(wtimeUsed, sb);
13276                    sb.append(" (");
13277                    sb.append((wtimeUsed*100)/realtimeSince);
13278                    sb.append("%)");
13279                    Slog.i(TAG, sb.toString());
13280                    sb.setLength(0);
13281                    sb.append("CPU for ");
13282                    app.toShortString(sb);
13283                    sb.append(": over ");
13284                    TimeUtils.formatDuration(uptimeSince, sb);
13285                    sb.append(" used ");
13286                    TimeUtils.formatDuration(cputimeUsed, sb);
13287                    sb.append(" (");
13288                    sb.append((cputimeUsed*100)/uptimeSince);
13289                    sb.append("%)");
13290                    Slog.i(TAG, sb.toString());
13291                }
13292                // If a process has held a wake lock for more
13293                // than 50% of the time during this period,
13294                // that sounds bad.  Kill!
13295                if (doWakeKills && realtimeSince > 0
13296                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13297                    synchronized (stats) {
13298                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13299                                realtimeSince, wtimeUsed);
13300                    }
13301                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13302                            + " (pid " + app.pid + "): held " + wtimeUsed
13303                            + " during " + realtimeSince);
13304                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13305                            app.processName, app.setAdj, "excessive wake lock");
13306                    Process.killProcessQuiet(app.pid);
13307                } else if (doCpuKills && uptimeSince > 0
13308                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13309                    synchronized (stats) {
13310                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13311                                uptimeSince, cputimeUsed);
13312                    }
13313                    Slog.w(TAG, "Excessive CPU in " + app.processName
13314                            + " (pid " + app.pid + "): used " + cputimeUsed
13315                            + " during " + uptimeSince);
13316                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13317                            app.processName, app.setAdj, "excessive cpu");
13318                    Process.killProcessQuiet(app.pid);
13319                } else {
13320                    app.lastWakeTime = wtime;
13321                    app.lastCpuTime = app.curCpuTime;
13322                }
13323            }
13324        }
13325    }
13326
13327    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13328            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13329        app.hiddenAdj = hiddenAdj;
13330        app.emptyAdj = emptyAdj;
13331
13332        if (app.thread == null) {
13333            return false;
13334        }
13335
13336        final boolean wasKeeping = app.keeping;
13337
13338        boolean success = true;
13339
13340        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13341
13342        if (app.curRawAdj != app.setRawAdj) {
13343            if (wasKeeping && !app.keeping) {
13344                // This app is no longer something we want to keep.  Note
13345                // its current wake lock time to later know to kill it if
13346                // it is not behaving well.
13347                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13348                synchronized (stats) {
13349                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13350                            app.pid, SystemClock.elapsedRealtime());
13351                }
13352                app.lastCpuTime = app.curCpuTime;
13353            }
13354
13355            app.setRawAdj = app.curRawAdj;
13356        }
13357
13358        if (app.curAdj != app.setAdj) {
13359            if (Process.setOomAdj(app.pid, app.curAdj)) {
13360                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13361                    TAG, "Set " + app.pid + " " + app.processName +
13362                    " adj " + app.curAdj + ": " + app.adjType);
13363                app.setAdj = app.curAdj;
13364            } else {
13365                success = false;
13366                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13367            }
13368        }
13369        if (app.setSchedGroup != app.curSchedGroup) {
13370            app.setSchedGroup = app.curSchedGroup;
13371            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13372                    "Setting process group of " + app.processName
13373                    + " to " + app.curSchedGroup);
13374            if (app.waitingToKill != null &&
13375                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13376                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13377                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13378                        app.processName, app.setAdj, app.waitingToKill);
13379                app.killedBackground = true;
13380                Process.killProcessQuiet(app.pid);
13381                success = false;
13382            } else {
13383                if (true) {
13384                    long oldId = Binder.clearCallingIdentity();
13385                    try {
13386                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13387                    } catch (Exception e) {
13388                        Slog.w(TAG, "Failed setting process group of " + app.pid
13389                                + " to " + app.curSchedGroup);
13390                        e.printStackTrace();
13391                    } finally {
13392                        Binder.restoreCallingIdentity(oldId);
13393                    }
13394                } else {
13395                    if (app.thread != null) {
13396                        try {
13397                            app.thread.setSchedulingGroup(app.curSchedGroup);
13398                        } catch (RemoteException e) {
13399                        }
13400                    }
13401                }
13402            }
13403        }
13404        return success;
13405    }
13406
13407    private final ActivityRecord resumedAppLocked() {
13408        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13409        if (resumedActivity == null || resumedActivity.app == null) {
13410            resumedActivity = mMainStack.mPausingActivity;
13411            if (resumedActivity == null || resumedActivity.app == null) {
13412                resumedActivity = mMainStack.topRunningActivityLocked(null);
13413            }
13414        }
13415        return resumedActivity;
13416    }
13417
13418    final boolean updateOomAdjLocked(ProcessRecord app) {
13419        final ActivityRecord TOP_ACT = resumedAppLocked();
13420        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13421        int curAdj = app.curAdj;
13422        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13423            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13424
13425        mAdjSeq++;
13426
13427        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13428                TOP_APP, false);
13429        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13430            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13431        if (nowHidden != wasHidden) {
13432            // Changed to/from hidden state, so apps after it in the LRU
13433            // list may also be changed.
13434            updateOomAdjLocked();
13435        }
13436        return success;
13437    }
13438
13439    final void updateOomAdjLocked() {
13440        final ActivityRecord TOP_ACT = resumedAppLocked();
13441        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13442
13443        if (false) {
13444            RuntimeException e = new RuntimeException();
13445            e.fillInStackTrace();
13446            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13447        }
13448
13449        mAdjSeq++;
13450        mNewNumServiceProcs = 0;
13451
13452        // Let's determine how many processes we have running vs.
13453        // how many slots we have for background processes; we may want
13454        // to put multiple processes in a slot of there are enough of
13455        // them.
13456        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13457                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13458        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13459        if (emptyFactor < 1) emptyFactor = 1;
13460        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13461        if (hiddenFactor < 1) hiddenFactor = 1;
13462        int stepHidden = 0;
13463        int stepEmpty = 0;
13464        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13465        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13466        int numHidden = 0;
13467        int numEmpty = 0;
13468        int numTrimming = 0;
13469
13470        mNumNonHiddenProcs = 0;
13471        mNumHiddenProcs = 0;
13472
13473        // First update the OOM adjustment for each of the
13474        // application processes based on their current state.
13475        int i = mLruProcesses.size();
13476        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13477        int nextHiddenAdj = curHiddenAdj+1;
13478        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13479        int nextEmptyAdj = curEmptyAdj+2;
13480        while (i > 0) {
13481            i--;
13482            ProcessRecord app = mLruProcesses.get(i);
13483            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13484            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13485            if (!app.killedBackground) {
13486                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13487                    // This process was assigned as a hidden process...  step the
13488                    // hidden level.
13489                    mNumHiddenProcs++;
13490                    if (curHiddenAdj != nextHiddenAdj) {
13491                        stepHidden++;
13492                        if (stepHidden >= hiddenFactor) {
13493                            stepHidden = 0;
13494                            curHiddenAdj = nextHiddenAdj;
13495                            nextHiddenAdj += 2;
13496                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13497                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13498                            }
13499                        }
13500                    }
13501                    numHidden++;
13502                    if (numHidden > hiddenProcessLimit) {
13503                        Slog.i(TAG, "No longer want " + app.processName
13504                                + " (pid " + app.pid + "): hidden #" + numHidden);
13505                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13506                                app.processName, app.setAdj, "too many background");
13507                        app.killedBackground = true;
13508                        Process.killProcessQuiet(app.pid);
13509                    }
13510                } else {
13511                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13512                        // This process was assigned as an empty process...  step the
13513                        // empty level.
13514                        if (curEmptyAdj != nextEmptyAdj) {
13515                            stepEmpty++;
13516                            if (stepEmpty >= emptyFactor) {
13517                                stepEmpty = 0;
13518                                curEmptyAdj = nextEmptyAdj;
13519                                nextEmptyAdj += 2;
13520                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13521                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13522                                }
13523                            }
13524                        }
13525                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13526                        mNumNonHiddenProcs++;
13527                    }
13528                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13529                        numEmpty++;
13530                        if (numEmpty > emptyProcessLimit) {
13531                            Slog.i(TAG, "No longer want " + app.processName
13532                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13533                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13534                                    app.processName, app.setAdj, "too many background");
13535                            app.killedBackground = true;
13536                            Process.killProcessQuiet(app.pid);
13537                        }
13538                    }
13539                }
13540                if (app.isolated && app.services.size() <= 0) {
13541                    // If this is an isolated process, and there are no
13542                    // services running in it, then the process is no longer
13543                    // needed.  We agressively kill these because we can by
13544                    // definition not re-use the same process again, and it is
13545                    // good to avoid having whatever code was running in them
13546                    // left sitting around after no longer needed.
13547                    Slog.i(TAG, "Isolated process " + app.processName
13548                            + " (pid " + app.pid + ") no longer needed");
13549                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13550                            app.processName, app.setAdj, "isolated not needed");
13551                    app.killedBackground = true;
13552                    Process.killProcessQuiet(app.pid);
13553                }
13554                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13555                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13556                        && !app.killedBackground) {
13557                    numTrimming++;
13558                }
13559            }
13560        }
13561
13562        mNumServiceProcs = mNewNumServiceProcs;
13563
13564        // Now determine the memory trimming level of background processes.
13565        // Unfortunately we need to start at the back of the list to do this
13566        // properly.  We only do this if the number of background apps we
13567        // are managing to keep around is less than half the maximum we desire;
13568        // if we are keeping a good number around, we'll let them use whatever
13569        // memory they want.
13570        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13571                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13572            final int numHiddenAndEmpty = numHidden + numEmpty;
13573            final int N = mLruProcesses.size();
13574            int factor = numTrimming/3;
13575            int minFactor = 2;
13576            if (mHomeProcess != null) minFactor++;
13577            if (mPreviousProcess != null) minFactor++;
13578            if (factor < minFactor) factor = minFactor;
13579            int step = 0;
13580            int fgTrimLevel;
13581            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13582                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13583            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13584                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13585            } else {
13586                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13587            }
13588            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13589            for (i=0; i<N; i++) {
13590                ProcessRecord app = mLruProcesses.get(i);
13591                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13592                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13593                        && !app.killedBackground) {
13594                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13595                        try {
13596                            app.thread.scheduleTrimMemory(curLevel);
13597                        } catch (RemoteException e) {
13598                        }
13599                        if (false) {
13600                            // For now we won't do this; our memory trimming seems
13601                            // to be good enough at this point that destroying
13602                            // activities causes more harm than good.
13603                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13604                                    && app != mHomeProcess && app != mPreviousProcess) {
13605                                // Need to do this on its own message because the stack may not
13606                                // be in a consistent state at this point.
13607                                // For these apps we will also finish their activities
13608                                // to help them free memory.
13609                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13610                            }
13611                        }
13612                    }
13613                    app.trimMemoryLevel = curLevel;
13614                    step++;
13615                    if (step >= factor) {
13616                        step = 0;
13617                        switch (curLevel) {
13618                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13619                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13620                                break;
13621                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13622                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13623                                break;
13624                        }
13625                    }
13626                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13627                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13628                            && app.thread != null) {
13629                        try {
13630                            app.thread.scheduleTrimMemory(
13631                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13632                        } catch (RemoteException e) {
13633                        }
13634                    }
13635                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13636                } else {
13637                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13638                            && app.pendingUiClean) {
13639                        // If this application is now in the background and it
13640                        // had done UI, then give it the special trim level to
13641                        // have it free UI resources.
13642                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13643                        if (app.trimMemoryLevel < level && app.thread != null) {
13644                            try {
13645                                app.thread.scheduleTrimMemory(level);
13646                            } catch (RemoteException e) {
13647                            }
13648                        }
13649                        app.pendingUiClean = false;
13650                    }
13651                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13652                        try {
13653                            app.thread.scheduleTrimMemory(fgTrimLevel);
13654                        } catch (RemoteException e) {
13655                        }
13656                    }
13657                    app.trimMemoryLevel = fgTrimLevel;
13658                }
13659            }
13660        } else {
13661            final int N = mLruProcesses.size();
13662            for (i=0; i<N; i++) {
13663                ProcessRecord app = mLruProcesses.get(i);
13664                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13665                        && app.pendingUiClean) {
13666                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13667                            && app.thread != null) {
13668                        try {
13669                            app.thread.scheduleTrimMemory(
13670                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13671                        } catch (RemoteException e) {
13672                        }
13673                    }
13674                    app.pendingUiClean = false;
13675                }
13676                app.trimMemoryLevel = 0;
13677            }
13678        }
13679
13680        if (mAlwaysFinishActivities) {
13681            // Need to do this on its own message because the stack may not
13682            // be in a consistent state at this point.
13683            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13684        }
13685    }
13686
13687    final void trimApplications() {
13688        synchronized (this) {
13689            int i;
13690
13691            // First remove any unused application processes whose package
13692            // has been removed.
13693            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13694                final ProcessRecord app = mRemovedProcesses.get(i);
13695                if (app.activities.size() == 0
13696                        && app.curReceiver == null && app.services.size() == 0) {
13697                    Slog.i(
13698                        TAG, "Exiting empty application process "
13699                        + app.processName + " ("
13700                        + (app.thread != null ? app.thread.asBinder() : null)
13701                        + ")\n");
13702                    if (app.pid > 0 && app.pid != MY_PID) {
13703                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13704                                app.processName, app.setAdj, "empty");
13705                        Process.killProcessQuiet(app.pid);
13706                    } else {
13707                        try {
13708                            app.thread.scheduleExit();
13709                        } catch (Exception e) {
13710                            // Ignore exceptions.
13711                        }
13712                    }
13713                    cleanUpApplicationRecordLocked(app, false, true, -1);
13714                    mRemovedProcesses.remove(i);
13715
13716                    if (app.persistent) {
13717                        if (app.persistent) {
13718                            addAppLocked(app.info, false);
13719                        }
13720                    }
13721                }
13722            }
13723
13724            // Now update the oom adj for all processes.
13725            updateOomAdjLocked();
13726        }
13727    }
13728
13729    /** This method sends the specified signal to each of the persistent apps */
13730    public void signalPersistentProcesses(int sig) throws RemoteException {
13731        if (sig != Process.SIGNAL_USR1) {
13732            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13733        }
13734
13735        synchronized (this) {
13736            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13737                    != PackageManager.PERMISSION_GRANTED) {
13738                throw new SecurityException("Requires permission "
13739                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13740            }
13741
13742            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13743                ProcessRecord r = mLruProcesses.get(i);
13744                if (r.thread != null && r.persistent) {
13745                    Process.sendSignal(r.pid, sig);
13746                }
13747            }
13748        }
13749    }
13750
13751    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13752        if (proc == null || proc == mProfileProc) {
13753            proc = mProfileProc;
13754            path = mProfileFile;
13755            profileType = mProfileType;
13756            clearProfilerLocked();
13757        }
13758        if (proc == null) {
13759            return;
13760        }
13761        try {
13762            proc.thread.profilerControl(false, path, null, profileType);
13763        } catch (RemoteException e) {
13764            throw new IllegalStateException("Process disappeared");
13765        }
13766    }
13767
13768    private void clearProfilerLocked() {
13769        if (mProfileFd != null) {
13770            try {
13771                mProfileFd.close();
13772            } catch (IOException e) {
13773            }
13774        }
13775        mProfileApp = null;
13776        mProfileProc = null;
13777        mProfileFile = null;
13778        mProfileType = 0;
13779        mAutoStopProfiler = false;
13780    }
13781
13782    public boolean profileControl(String process, int userId, boolean start,
13783            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13784
13785        try {
13786            synchronized (this) {
13787                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13788                // its own permission.
13789                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13790                        != PackageManager.PERMISSION_GRANTED) {
13791                    throw new SecurityException("Requires permission "
13792                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13793                }
13794
13795                if (start && fd == null) {
13796                    throw new IllegalArgumentException("null fd");
13797                }
13798
13799                ProcessRecord proc = null;
13800                if (process != null) {
13801                    proc = findProcessLocked(process, userId, "profileControl");
13802                }
13803
13804                if (start && (proc == null || proc.thread == null)) {
13805                    throw new IllegalArgumentException("Unknown process: " + process);
13806                }
13807
13808                if (start) {
13809                    stopProfilerLocked(null, null, 0);
13810                    setProfileApp(proc.info, proc.processName, path, fd, false);
13811                    mProfileProc = proc;
13812                    mProfileType = profileType;
13813                    try {
13814                        fd = fd.dup();
13815                    } catch (IOException e) {
13816                        fd = null;
13817                    }
13818                    proc.thread.profilerControl(start, path, fd, profileType);
13819                    fd = null;
13820                    mProfileFd = null;
13821                } else {
13822                    stopProfilerLocked(proc, path, profileType);
13823                    if (fd != null) {
13824                        try {
13825                            fd.close();
13826                        } catch (IOException e) {
13827                        }
13828                    }
13829                }
13830
13831                return true;
13832            }
13833        } catch (RemoteException e) {
13834            throw new IllegalStateException("Process disappeared");
13835        } finally {
13836            if (fd != null) {
13837                try {
13838                    fd.close();
13839                } catch (IOException e) {
13840                }
13841            }
13842        }
13843    }
13844
13845    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13846        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13847                userId, true, true, callName, null);
13848        ProcessRecord proc = null;
13849        try {
13850            int pid = Integer.parseInt(process);
13851            synchronized (mPidsSelfLocked) {
13852                proc = mPidsSelfLocked.get(pid);
13853            }
13854        } catch (NumberFormatException e) {
13855        }
13856
13857        if (proc == null) {
13858            HashMap<String, SparseArray<ProcessRecord>> all
13859                    = mProcessNames.getMap();
13860            SparseArray<ProcessRecord> procs = all.get(process);
13861            if (procs != null && procs.size() > 0) {
13862                proc = procs.valueAt(0);
13863                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13864                    for (int i=1; i<procs.size(); i++) {
13865                        ProcessRecord thisProc = procs.valueAt(i);
13866                        if (thisProc.userId == userId) {
13867                            proc = thisProc;
13868                            break;
13869                        }
13870                    }
13871                }
13872            }
13873        }
13874
13875        return proc;
13876    }
13877
13878    public boolean dumpHeap(String process, int userId, boolean managed,
13879            String path, ParcelFileDescriptor fd) throws RemoteException {
13880
13881        try {
13882            synchronized (this) {
13883                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13884                // its own permission (same as profileControl).
13885                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13886                        != PackageManager.PERMISSION_GRANTED) {
13887                    throw new SecurityException("Requires permission "
13888                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13889                }
13890
13891                if (fd == null) {
13892                    throw new IllegalArgumentException("null fd");
13893                }
13894
13895                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13896                if (proc == null || proc.thread == null) {
13897                    throw new IllegalArgumentException("Unknown process: " + process);
13898                }
13899
13900                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13901                if (!isDebuggable) {
13902                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13903                        throw new SecurityException("Process not debuggable: " + proc);
13904                    }
13905                }
13906
13907                proc.thread.dumpHeap(managed, path, fd);
13908                fd = null;
13909                return true;
13910            }
13911        } catch (RemoteException e) {
13912            throw new IllegalStateException("Process disappeared");
13913        } finally {
13914            if (fd != null) {
13915                try {
13916                    fd.close();
13917                } catch (IOException e) {
13918                }
13919            }
13920        }
13921    }
13922
13923    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13924    public void monitor() {
13925        synchronized (this) { }
13926    }
13927
13928    void onCoreSettingsChange(Bundle settings) {
13929        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13930            ProcessRecord processRecord = mLruProcesses.get(i);
13931            try {
13932                if (processRecord.thread != null) {
13933                    processRecord.thread.setCoreSettings(settings);
13934                }
13935            } catch (RemoteException re) {
13936                /* ignore */
13937            }
13938        }
13939    }
13940
13941    // Multi-user methods
13942
13943    @Override
13944    public boolean switchUser(int userId) {
13945        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13946                != PackageManager.PERMISSION_GRANTED) {
13947            String msg = "Permission Denial: switchUser() from pid="
13948                    + Binder.getCallingPid()
13949                    + ", uid=" + Binder.getCallingUid()
13950                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13951            Slog.w(TAG, msg);
13952            throw new SecurityException(msg);
13953        }
13954
13955        final long ident = Binder.clearCallingIdentity();
13956        try {
13957            synchronized (this) {
13958                final int oldUserId = mCurrentUserId;
13959                if (oldUserId == userId) {
13960                    return true;
13961                }
13962
13963                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
13964                if (userInfo == null) {
13965                    Slog.w(TAG, "No user info for user #" + userId);
13966                    return false;
13967                }
13968
13969                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13970                        R.anim.screen_user_enter);
13971
13972                // If the user we are switching to is not currently started, then
13973                // we need to start it now.
13974                if (mStartedUsers.get(userId) == null) {
13975                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13976                    updateStartedUserArrayLocked();
13977                }
13978
13979                mCurrentUserId = userId;
13980                mCurrentUserArray = new int[] { userId };
13981                final Integer userIdInt = Integer.valueOf(userId);
13982                mUserLru.remove(userIdInt);
13983                mUserLru.add(userIdInt);
13984
13985                mWindowManager.setCurrentUser(userId);
13986
13987                final UserStartedState uss = mStartedUsers.get(userId);
13988
13989                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
13990                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
13991                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
13992                        oldUserId, userId, uss));
13993                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
13994                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
13995                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13997                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13998                broadcastIntentLocked(null, null, intent,
13999                        null, null, 0, null, null, null,
14000                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14001
14002                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14003                    if (userId != 0) {
14004                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14005                        broadcastIntentLocked(null, null, intent, null,
14006                                new IIntentReceiver.Stub() {
14007                                    public void performReceive(Intent intent, int resultCode,
14008                                            String data, Bundle extras, boolean ordered,
14009                                            boolean sticky, int sendingUser) {
14010                                        synchronized (ActivityManagerService.this) {
14011                                            getUserManagerLocked().makeInitialized(userInfo.id);
14012                                        }
14013                                    }
14014                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14015                                userId);
14016                    } else {
14017                        getUserManagerLocked().makeInitialized(userInfo.id);
14018                    }
14019                }
14020
14021                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14022                if (!haveActivities) {
14023                    startHomeActivityLocked(userId);
14024                }
14025
14026                getUserManagerLocked().userForeground(userId);
14027                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14028            }
14029        } finally {
14030            Binder.restoreCallingIdentity(ident);
14031        }
14032
14033        return true;
14034    }
14035
14036    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14037        long ident = Binder.clearCallingIdentity();
14038        try {
14039            Intent intent;
14040            if (oldUserId >= 0) {
14041                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14043                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14044                broadcastIntentLocked(null, null, intent,
14045                        null, null, 0, null, null, null,
14046                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14047            }
14048            if (newUserId >= 0) {
14049                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14050                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14051                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14052                broadcastIntentLocked(null, null, intent,
14053                        null, null, 0, null, null, null,
14054                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14055                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14056                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14057                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14058                broadcastIntentLocked(null, null, intent,
14059                        null, null, 0, null, null,
14060                        android.Manifest.permission.MANAGE_USERS,
14061                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14062            }
14063        } finally {
14064            Binder.restoreCallingIdentity(ident);
14065        }
14066    }
14067
14068    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14069            final int newUserId) {
14070        final int N = mUserSwitchObservers.beginBroadcast();
14071        if (N > 0) {
14072            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14073                int mCount = 0;
14074                @Override
14075                public void sendResult(Bundle data) throws RemoteException {
14076                    synchronized (ActivityManagerService.this) {
14077                        if (mCurUserSwitchCallback == this) {
14078                            mCount++;
14079                            if (mCount == N) {
14080                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14081                            }
14082                        }
14083                    }
14084                }
14085            };
14086            synchronized (this) {
14087                mCurUserSwitchCallback = callback;
14088            }
14089            for (int i=0; i<N; i++) {
14090                try {
14091                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14092                            newUserId, callback);
14093                } catch (RemoteException e) {
14094                }
14095            }
14096        } else {
14097            synchronized (this) {
14098                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14099            }
14100        }
14101        mUserSwitchObservers.finishBroadcast();
14102    }
14103
14104    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14105        synchronized (this) {
14106            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14107            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14108        }
14109    }
14110
14111    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14112        mCurUserSwitchCallback = null;
14113        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14114        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14115                oldUserId, newUserId, uss));
14116    }
14117
14118    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14119        final int N = mUserSwitchObservers.beginBroadcast();
14120        for (int i=0; i<N; i++) {
14121            try {
14122                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14123            } catch (RemoteException e) {
14124            }
14125        }
14126        mUserSwitchObservers.finishBroadcast();
14127        synchronized (this) {
14128            mWindowManager.stopFreezingScreen();
14129        }
14130    }
14131
14132    void finishUserSwitch(UserStartedState uss) {
14133        synchronized (this) {
14134            if (uss.mState == UserStartedState.STATE_BOOTING
14135                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14136                uss.mState = UserStartedState.STATE_RUNNING;
14137                final int userId = uss.mHandle.getIdentifier();
14138                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14139                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14140                broadcastIntentLocked(null, null, intent,
14141                        null, null, 0, null, null,
14142                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14143                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14144            }
14145            int num = mUserLru.size();
14146            int i = 0;
14147            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14148                Integer oldUserId = mUserLru.get(i);
14149                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14150                if (oldUss == null) {
14151                    // Shouldn't happen, but be sane if it does.
14152                    mUserLru.remove(i);
14153                    num--;
14154                    continue;
14155                }
14156                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14157                    // This user is already stopping, doesn't count.
14158                    num--;
14159                    i++;
14160                    continue;
14161                }
14162                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14163                    // Owner and current can't be stopped, but count as running.
14164                    i++;
14165                    continue;
14166                }
14167                // This is a user to be stopped.
14168                stopUserLocked(oldUserId, null);
14169                num--;
14170                i++;
14171            }
14172        }
14173    }
14174
14175    @Override
14176    public int stopUser(final int userId, final IStopUserCallback callback) {
14177        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14178                != PackageManager.PERMISSION_GRANTED) {
14179            String msg = "Permission Denial: switchUser() from pid="
14180                    + Binder.getCallingPid()
14181                    + ", uid=" + Binder.getCallingUid()
14182                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14183            Slog.w(TAG, msg);
14184            throw new SecurityException(msg);
14185        }
14186        if (userId <= 0) {
14187            throw new IllegalArgumentException("Can't stop primary user " + userId);
14188        }
14189        synchronized (this) {
14190            return stopUserLocked(userId, callback);
14191        }
14192    }
14193
14194    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14195        if (mCurrentUserId == userId) {
14196            return ActivityManager.USER_OP_IS_CURRENT;
14197        }
14198
14199        final UserStartedState uss = mStartedUsers.get(userId);
14200        if (uss == null) {
14201            // User is not started, nothing to do...  but we do need to
14202            // callback if requested.
14203            if (callback != null) {
14204                mHandler.post(new Runnable() {
14205                    @Override
14206                    public void run() {
14207                        try {
14208                            callback.userStopped(userId);
14209                        } catch (RemoteException e) {
14210                        }
14211                    }
14212                });
14213            }
14214            return ActivityManager.USER_OP_SUCCESS;
14215        }
14216
14217        if (callback != null) {
14218            uss.mStopCallbacks.add(callback);
14219        }
14220
14221        if (uss.mState != UserStartedState.STATE_STOPPING) {
14222            uss.mState = UserStartedState.STATE_STOPPING;
14223
14224            long ident = Binder.clearCallingIdentity();
14225            try {
14226                // Inform of user switch
14227                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14228                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14229                    @Override
14230                    public void performReceive(Intent intent, int resultCode, String data,
14231                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14232                        finishUserStop(uss);
14233                    }
14234                };
14235                broadcastIntentLocked(null, null, intent,
14236                        null, resultReceiver, 0, null, null, null,
14237                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14238            } finally {
14239                Binder.restoreCallingIdentity(ident);
14240            }
14241        }
14242
14243        return ActivityManager.USER_OP_SUCCESS;
14244    }
14245
14246    void finishUserStop(UserStartedState uss) {
14247        final int userId = uss.mHandle.getIdentifier();
14248        boolean stopped;
14249        ArrayList<IStopUserCallback> callbacks;
14250        synchronized (this) {
14251            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14252            if (uss.mState != UserStartedState.STATE_STOPPING
14253                    || mStartedUsers.get(userId) != uss) {
14254                stopped = false;
14255            } else {
14256                stopped = true;
14257                // User can no longer run.
14258                mStartedUsers.remove(userId);
14259                mUserLru.remove(Integer.valueOf(userId));
14260                updateStartedUserArrayLocked();
14261
14262                // Clean up all state and processes associated with the user.
14263                // Kill all the processes for the user.
14264                forceStopUserLocked(userId);
14265            }
14266        }
14267
14268        for (int i=0; i<callbacks.size(); i++) {
14269            try {
14270                if (stopped) callbacks.get(i).userStopped(userId);
14271                else callbacks.get(i).userStopAborted(userId);
14272            } catch (RemoteException e) {
14273            }
14274        }
14275    }
14276
14277    @Override
14278    public UserInfo getCurrentUser() {
14279        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14280                != PackageManager.PERMISSION_GRANTED) && (
14281                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14282                != PackageManager.PERMISSION_GRANTED)) {
14283            String msg = "Permission Denial: getCurrentUser() from pid="
14284                    + Binder.getCallingPid()
14285                    + ", uid=" + Binder.getCallingUid()
14286                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14287            Slog.w(TAG, msg);
14288            throw new SecurityException(msg);
14289        }
14290        synchronized (this) {
14291            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14292        }
14293    }
14294
14295    int getCurrentUserIdLocked() {
14296        return mCurrentUserId;
14297    }
14298
14299    @Override
14300    public boolean isUserRunning(int userId) {
14301        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14302                != PackageManager.PERMISSION_GRANTED) {
14303            String msg = "Permission Denial: isUserRunning() from pid="
14304                    + Binder.getCallingPid()
14305                    + ", uid=" + Binder.getCallingUid()
14306                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14307            Slog.w(TAG, msg);
14308            throw new SecurityException(msg);
14309        }
14310        synchronized (this) {
14311            return isUserRunningLocked(userId);
14312        }
14313    }
14314
14315    boolean isUserRunningLocked(int userId) {
14316        UserStartedState state = mStartedUsers.get(userId);
14317        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14318    }
14319
14320    @Override
14321    public int[] getRunningUserIds() {
14322        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14323                != PackageManager.PERMISSION_GRANTED) {
14324            String msg = "Permission Denial: isUserRunning() from pid="
14325                    + Binder.getCallingPid()
14326                    + ", uid=" + Binder.getCallingUid()
14327                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14328            Slog.w(TAG, msg);
14329            throw new SecurityException(msg);
14330        }
14331        synchronized (this) {
14332            return mStartedUserArray;
14333        }
14334    }
14335
14336    private void updateStartedUserArrayLocked() {
14337        mStartedUserArray = new int[mStartedUsers.size()];
14338        for (int i=0; i<mStartedUsers.size();  i++) {
14339            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14340        }
14341    }
14342
14343    @Override
14344    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14345        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14346                != PackageManager.PERMISSION_GRANTED) {
14347            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14348                    + Binder.getCallingPid()
14349                    + ", uid=" + Binder.getCallingUid()
14350                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14351            Slog.w(TAG, msg);
14352            throw new SecurityException(msg);
14353        }
14354
14355        mUserSwitchObservers.register(observer);
14356    }
14357
14358    @Override
14359    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14360        mUserSwitchObservers.unregister(observer);
14361    }
14362
14363    private boolean userExists(int userId) {
14364        if (userId == 0) {
14365            return true;
14366        }
14367        UserManagerService ums = getUserManagerLocked();
14368        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14369    }
14370
14371    int[] getUsersLocked() {
14372        UserManagerService ums = getUserManagerLocked();
14373        return ums != null ? ums.getUserIds() : new int[] { 0 };
14374    }
14375
14376    UserManagerService getUserManagerLocked() {
14377        if (mUserManager == null) {
14378            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14379            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14380        }
14381        return mUserManager;
14382    }
14383
14384    private void checkValidCaller(int uid, int userId) {
14385        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14386
14387        throw new SecurityException("Caller uid=" + uid
14388                + " is not privileged to communicate with user=" + userId);
14389    }
14390
14391    private int applyUserId(int uid, int userId) {
14392        return UserHandle.getUid(userId, uid);
14393    }
14394
14395    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14396        if (info == null) return null;
14397        ApplicationInfo newInfo = new ApplicationInfo(info);
14398        newInfo.uid = applyUserId(info.uid, userId);
14399        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14400                + info.packageName;
14401        return newInfo;
14402    }
14403
14404    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14405        if (aInfo == null
14406                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14407            return aInfo;
14408        }
14409
14410        ActivityInfo info = new ActivityInfo(aInfo);
14411        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14412        return info;
14413    }
14414}
14415