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