ActivityManagerService.java revision 5b1ada2562c17921adf6a62ea62bcb445160983c
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.IThumbnailReceiver;
51import android.app.Instrumentation;
52import android.app.Notification;
53import android.app.NotificationManager;
54import android.app.PendingIntent;
55import android.app.Service;
56import android.app.backup.IBackupManager;
57import android.content.ActivityNotFoundException;
58import android.content.BroadcastReceiver;
59import android.content.ClipData;
60import android.content.ComponentCallbacks2;
61import android.content.ComponentName;
62import android.content.ContentProvider;
63import android.content.ContentResolver;
64import android.content.Context;
65import android.content.DialogInterface;
66import android.content.IContentProvider;
67import android.content.IIntentReceiver;
68import android.content.IIntentSender;
69import android.content.Intent;
70import android.content.IntentFilter;
71import android.content.IntentSender;
72import android.content.pm.ActivityInfo;
73import android.content.pm.ApplicationInfo;
74import android.content.pm.ConfigurationInfo;
75import android.content.pm.IPackageDataObserver;
76import android.content.pm.IPackageManager;
77import android.content.pm.InstrumentationInfo;
78import android.content.pm.PackageInfo;
79import android.content.pm.PackageManager;
80import android.content.pm.UserInfo;
81import android.content.pm.PackageManager.NameNotFoundException;
82import android.content.pm.PathPermission;
83import android.content.pm.ProviderInfo;
84import android.content.pm.ResolveInfo;
85import android.content.pm.ServiceInfo;
86import android.content.res.CompatibilityInfo;
87import android.content.res.Configuration;
88import android.graphics.Bitmap;
89import android.net.Proxy;
90import android.net.ProxyProperties;
91import android.net.Uri;
92import android.os.Binder;
93import android.os.Build;
94import android.os.Bundle;
95import android.os.Debug;
96import android.os.DropBoxManager;
97import android.os.Environment;
98import android.os.FileObserver;
99import android.os.FileUtils;
100import android.os.Handler;
101import android.os.IBinder;
102import android.os.IPermissionController;
103import android.os.Looper;
104import android.os.Message;
105import android.os.Parcel;
106import android.os.ParcelFileDescriptor;
107import android.os.Process;
108import android.os.RemoteCallbackList;
109import android.os.RemoteException;
110import android.os.ServiceManager;
111import android.os.StrictMode;
112import android.os.SystemClock;
113import android.os.SystemProperties;
114import android.os.UserId;
115import android.os.UserManager;
116import android.provider.Settings;
117import android.text.format.Time;
118import android.util.EventLog;
119import android.util.Log;
120import android.util.Pair;
121import android.util.PrintWriterPrinter;
122import android.util.Slog;
123import android.util.SparseArray;
124import android.util.SparseIntArray;
125import android.util.TimeUtils;
126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
134import java.io.BufferedReader;
135import java.io.DataInputStream;
136import java.io.DataOutputStream;
137import java.io.File;
138import java.io.FileDescriptor;
139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
141import java.io.FileOutputStream;
142import java.io.IOException;
143import java.io.InputStreamReader;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
148import java.util.Collection;
149import java.util.Collections;
150import java.util.Comparator;
151import java.util.HashMap;
152import java.util.HashSet;
153import java.util.Iterator;
154import java.util.List;
155import java.util.Locale;
156import java.util.Map;
157import java.util.Map.Entry;
158import java.util.Set;
159import java.util.concurrent.atomic.AtomicBoolean;
160import java.util.concurrent.atomic.AtomicLong;
161
162public final class ActivityManagerService extends ActivityManagerNative
163        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
164    private static final String USER_DATA_DIR = "/data/user/";
165    static final String TAG = "ActivityManager";
166    static final String TAG_MU = "ActivityManagerServiceMU";
167    static final boolean DEBUG = false;
168    static final boolean localLOGV = DEBUG;
169    static final boolean DEBUG_SWITCH = localLOGV || false;
170    static final boolean DEBUG_TASKS = localLOGV || false;
171    static final boolean DEBUG_PAUSE = localLOGV || false;
172    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
173    static final boolean DEBUG_TRANSITION = localLOGV || false;
174    static final boolean DEBUG_BROADCAST = localLOGV || false;
175    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
177    static final boolean DEBUG_SERVICE = localLOGV || false;
178    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
179    static final boolean DEBUG_VISBILITY = localLOGV || false;
180    static final boolean DEBUG_PROCESSES = localLOGV || false;
181    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
182    static final boolean DEBUG_PROVIDER = localLOGV || false;
183    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
184    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
185    static final boolean DEBUG_RESULTS = localLOGV || false;
186    static final boolean DEBUG_BACKUP = localLOGV || false;
187    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
188    static final boolean DEBUG_POWER = localLOGV || false;
189    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
190    static final boolean DEBUG_MU = localLOGV || false;
191    static final boolean VALIDATE_TOKENS = false;
192    static final boolean SHOW_ACTIVITY_START_TIME = true;
193
194    // Control over CPU and battery monitoring.
195    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
196    static final boolean MONITOR_CPU_USAGE = true;
197    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
198    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
199    static final boolean MONITOR_THREAD_CPU_USAGE = false;
200
201    // The flags that are set for all calls we make to the package manager.
202    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
203
204    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
205
206    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
207
208    // Maximum number of recent tasks that we can remember.
209    static final int MAX_RECENT_TASKS = 20;
210
211    // Amount of time after a call to stopAppSwitches() during which we will
212    // prevent further untrusted switches from happening.
213    static final long APP_SWITCH_DELAY_TIME = 5*1000;
214
215    // How long we wait for a launched process to attach to the activity manager
216    // before we decide it's never going to come up for real.
217    static final int PROC_START_TIMEOUT = 10*1000;
218
219    // How long we wait for a launched process to attach to the activity manager
220    // before we decide it's never going to come up for real, when the process was
221    // started with a wrapper for instrumentation (such as Valgrind) because it
222    // could take much longer than usual.
223    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
224
225    // How long to wait after going idle before forcing apps to GC.
226    static final int GC_TIMEOUT = 5*1000;
227
228    // The minimum amount of time between successive GC requests for a process.
229    static final int GC_MIN_INTERVAL = 60*1000;
230
231    // The rate at which we check for apps using excessive power -- 15 mins.
232    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
233
234    // The minimum sample duration we will allow before deciding we have
235    // enough data on wake locks to start killing things.
236    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on CPU usage to start killing things.
240    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // How long we allow a receiver to run before giving up on it.
243    static final int BROADCAST_FG_TIMEOUT = 10*1000;
244    static final int BROADCAST_BG_TIMEOUT = 60*1000;
245
246    // How long we wait until we timeout on key dispatching.
247    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
248
249    // How long we wait until we timeout on key dispatching during instrumentation.
250    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
251
252    static final int MY_PID = Process.myPid();
253
254    static final String[] EMPTY_STRING_ARRAY = new String[0];
255
256    public ActivityStack mMainStack;
257
258    private final boolean mHeadless;
259
260    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
261    // default actuion automatically.  Important for devices without direct input
262    // devices.
263    private boolean mShowDialogs = true;
264
265    /**
266     * Description of a request to start a new activity, which has been held
267     * due to app switches being disabled.
268     */
269    static class PendingActivityLaunch {
270        ActivityRecord r;
271        ActivityRecord sourceRecord;
272        int startFlags;
273    }
274
275    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276            = new ArrayList<PendingActivityLaunch>();
277
278
279    BroadcastQueue mFgBroadcastQueue;
280    BroadcastQueue mBgBroadcastQueue;
281    // Convenient for easy iteration over the queues. Foreground is first
282    // so that dispatch of foreground broadcasts gets precedence.
283    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
284
285    BroadcastQueue broadcastQueueForIntent(Intent intent) {
286        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
287        if (DEBUG_BACKGROUND_BROADCAST) {
288            Slog.i(TAG, "Broadcast intent " + intent + " on "
289                    + (isFg ? "foreground" : "background")
290                    + " queue");
291        }
292        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
293    }
294
295    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
296        for (BroadcastQueue queue : mBroadcastQueues) {
297            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
298            if (r != null) {
299                return r;
300            }
301        }
302        return null;
303    }
304
305    /**
306     * Activity we have told the window manager to have key focus.
307     */
308    ActivityRecord mFocusedActivity = null;
309    /**
310     * List of intents that were used to start the most recent tasks.
311     */
312    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
313
314    /**
315     * Process management.
316     */
317    final ProcessList mProcessList = new ProcessList();
318
319    /**
320     * All of the applications we currently have running organized by name.
321     * The keys are strings of the application package name (as
322     * returned by the package manager), and the keys are ApplicationRecord
323     * objects.
324     */
325    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
326
327    /**
328     * The currently running isolated processes.
329     */
330    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
331
332    /**
333     * Counter for assigning isolated process uids, to avoid frequently reusing the
334     * same ones.
335     */
336    int mNextIsolatedProcessUid = 0;
337
338    /**
339     * The currently running heavy-weight process, if any.
340     */
341    ProcessRecord mHeavyWeightProcess = null;
342
343    /**
344     * The last time that various processes have crashed.
345     */
346    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
347
348    /**
349     * Set of applications that we consider to be bad, and will reject
350     * incoming broadcasts from (which the user has no control over).
351     * Processes are added to this set when they have crashed twice within
352     * a minimum amount of time; they are removed from it when they are
353     * later restarted (hopefully due to some user action).  The value is the
354     * time it was added to the list.
355     */
356    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
357
358    /**
359     * All of the processes we currently have running organized by pid.
360     * The keys are the pid running the application.
361     *
362     * <p>NOTE: This object is protected by its own lock, NOT the global
363     * activity manager lock!
364     */
365    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
366
367    /**
368     * All of the processes that have been forced to be foreground.  The key
369     * is the pid of the caller who requested it (we hold a death
370     * link on it).
371     */
372    abstract class ForegroundToken implements IBinder.DeathRecipient {
373        int pid;
374        IBinder token;
375    }
376    final SparseArray<ForegroundToken> mForegroundProcesses
377            = new SparseArray<ForegroundToken>();
378
379    /**
380     * List of records for processes that someone had tried to start before the
381     * system was ready.  We don't start them at that point, but ensure they
382     * are started by the time booting is complete.
383     */
384    final ArrayList<ProcessRecord> mProcessesOnHold
385            = new ArrayList<ProcessRecord>();
386
387    /**
388     * List of persistent applications that are in the process
389     * of being started.
390     */
391    final ArrayList<ProcessRecord> mPersistentStartingProcesses
392            = new ArrayList<ProcessRecord>();
393
394    /**
395     * Processes that are being forcibly torn down.
396     */
397    final ArrayList<ProcessRecord> mRemovedProcesses
398            = new ArrayList<ProcessRecord>();
399
400    /**
401     * List of running applications, sorted by recent usage.
402     * The first entry in the list is the least recently used.
403     * It contains ApplicationRecord objects.  This list does NOT include
404     * any persistent application records (since we never want to exit them).
405     */
406    final ArrayList<ProcessRecord> mLruProcesses
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * List of processes that should gc as soon as things are idle.
411     */
412    final ArrayList<ProcessRecord> mProcessesToGc
413            = new ArrayList<ProcessRecord>();
414
415    /**
416     * This is the process holding what we currently consider to be
417     * the "home" activity.
418     */
419    ProcessRecord mHomeProcess;
420
421    /**
422     * This is the process holding the activity the user last visited that
423     * is in a different process from the one they are currently in.
424     */
425    ProcessRecord mPreviousProcess;
426
427    /**
428     * The time at which the previous process was last visible.
429     */
430    long mPreviousProcessVisibleTime;
431
432    /**
433     * Packages that the user has asked to have run in screen size
434     * compatibility mode instead of filling the screen.
435     */
436    final CompatModePackages mCompatModePackages;
437
438    /**
439     * Set of PendingResultRecord objects that are currently active.
440     */
441    final HashSet mPendingResultRecords = new HashSet();
442
443    /**
444     * Set of IntentSenderRecord objects that are currently active.
445     */
446    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
447            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
448
449    /**
450     * Fingerprints (hashCode()) of stack traces that we've
451     * already logged DropBox entries for.  Guarded by itself.  If
452     * something (rogue user app) forces this over
453     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
454     */
455    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
456    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
457
458    /**
459     * Strict Mode background batched logging state.
460     *
461     * The string buffer is guarded by itself, and its lock is also
462     * used to determine if another batched write is already
463     * in-flight.
464     */
465    private final StringBuilder mStrictModeBuffer = new StringBuilder();
466
467    /**
468     * Keeps track of all IIntentReceivers that have been registered for
469     * broadcasts.  Hash keys are the receiver IBinder, hash value is
470     * a ReceiverList.
471     */
472    final HashMap mRegisteredReceivers = new HashMap();
473
474    /**
475     * Resolver for broadcast intents to registered receivers.
476     * Holds BroadcastFilter (subclass of IntentFilter).
477     */
478    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
479            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
480        @Override
481        protected boolean allowFilterResult(
482                BroadcastFilter filter, List<BroadcastFilter> dest) {
483            IBinder target = filter.receiverList.receiver.asBinder();
484            for (int i=dest.size()-1; i>=0; i--) {
485                if (dest.get(i).receiverList.receiver.asBinder() == target) {
486                    return false;
487                }
488            }
489            return true;
490        }
491
492        @Override
493        protected BroadcastFilter[] newArray(int size) {
494            return new BroadcastFilter[size];
495        }
496
497        @Override
498        protected String packageForFilter(BroadcastFilter filter) {
499            return filter.packageName;
500        }
501    };
502
503    /**
504     * State of all active sticky broadcasts.  Keys are the action of the
505     * sticky Intent, values are an ArrayList of all broadcasted intents with
506     * that action (which should usually be one).
507     */
508    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
509            new HashMap<String, ArrayList<Intent>>();
510
511    final ActiveServices mServices;
512
513    /**
514     * Backup/restore process management
515     */
516    String mBackupAppName = null;
517    BackupRecord mBackupTarget = null;
518
519    /**
520     * List of PendingThumbnailsRecord objects of clients who are still
521     * waiting to receive all of the thumbnails for a task.
522     */
523    final ArrayList mPendingThumbnails = new ArrayList();
524
525    /**
526     * List of HistoryRecord objects that have been finished and must
527     * still report back to a pending thumbnail receiver.
528     */
529    final ArrayList mCancelledThumbnails = new ArrayList();
530
531    final ProviderMap mProviderMap = new ProviderMap();
532
533    /**
534     * List of content providers who have clients waiting for them.  The
535     * application is currently being launched and the provider will be
536     * removed from this list once it is published.
537     */
538    final ArrayList<ContentProviderRecord> mLaunchingProviders
539            = new ArrayList<ContentProviderRecord>();
540
541    /**
542     * Global set of specific Uri permissions that have been granted.
543     */
544    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
545            = new SparseArray<HashMap<Uri, UriPermission>>();
546
547    CoreSettingsObserver mCoreSettingsObserver;
548
549    /**
550     * Thread-local storage used to carry caller permissions over through
551     * indirect content-provider access.
552     * @see #ActivityManagerService.openContentUri()
553     */
554    private class Identity {
555        public int pid;
556        public int uid;
557
558        Identity(int _pid, int _uid) {
559            pid = _pid;
560            uid = _uid;
561        }
562    }
563
564    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
565
566    /**
567     * All information we have collected about the runtime performance of
568     * any user id that can impact battery performance.
569     */
570    final BatteryStatsService mBatteryStatsService;
571
572    /**
573     * information about component usage
574     */
575    final UsageStatsService mUsageStatsService;
576
577    /**
578     * Current configuration information.  HistoryRecord objects are given
579     * a reference to this object to indicate which configuration they are
580     * currently running in, so this object must be kept immutable.
581     */
582    Configuration mConfiguration = new Configuration();
583
584    /**
585     * Current sequencing integer of the configuration, for skipping old
586     * configurations.
587     */
588    int mConfigurationSeq = 0;
589
590    /**
591     * Hardware-reported OpenGLES version.
592     */
593    final int GL_ES_VERSION;
594
595    /**
596     * List of initialization arguments to pass to all processes when binding applications to them.
597     * For example, references to the commonly used services.
598     */
599    HashMap<String, IBinder> mAppBindArgs;
600
601    /**
602     * Temporary to avoid allocations.  Protected by main lock.
603     */
604    final StringBuilder mStringBuilder = new StringBuilder(256);
605
606    /**
607     * Used to control how we initialize the service.
608     */
609    boolean mStartRunning = false;
610    ComponentName mTopComponent;
611    String mTopAction;
612    String mTopData;
613    boolean mProcessesReady = false;
614    boolean mSystemReady = false;
615    boolean mBooting = false;
616    boolean mWaitingUpdate = false;
617    boolean mDidUpdate = false;
618    boolean mOnBattery = false;
619    boolean mLaunchWarningShown = false;
620
621    Context mContext;
622
623    int mFactoryTest;
624
625    boolean mCheckedForSetup;
626
627    /**
628     * The time at which we will allow normal application switches again,
629     * after a call to {@link #stopAppSwitches()}.
630     */
631    long mAppSwitchesAllowedTime;
632
633    /**
634     * This is set to true after the first switch after mAppSwitchesAllowedTime
635     * is set; any switches after that will clear the time.
636     */
637    boolean mDidAppSwitch;
638
639    /**
640     * Last time (in realtime) at which we checked for power usage.
641     */
642    long mLastPowerCheckRealtime;
643
644    /**
645     * Last time (in uptime) at which we checked for power usage.
646     */
647    long mLastPowerCheckUptime;
648
649    /**
650     * Set while we are wanting to sleep, to prevent any
651     * activities from being started/resumed.
652     */
653    boolean mSleeping = false;
654
655    /**
656     * State of external calls telling us if the device is asleep.
657     */
658    boolean mWentToSleep = false;
659
660    /**
661     * State of external call telling us if the lock screen is shown.
662     */
663    boolean mLockScreenShown = false;
664
665    /**
666     * Set if we are shutting down the system, similar to sleeping.
667     */
668    boolean mShuttingDown = false;
669
670    /**
671     * Task identifier that activities are currently being started
672     * in.  Incremented each time a new task is created.
673     * todo: Replace this with a TokenSpace class that generates non-repeating
674     * integers that won't wrap.
675     */
676    int mCurTask = 1;
677
678    /**
679     * Current sequence id for oom_adj computation traversal.
680     */
681    int mAdjSeq = 0;
682
683    /**
684     * Current sequence id for process LRU updating.
685     */
686    int mLruSeq = 0;
687
688    /**
689     * Keep track of the number of service processes we last found, to
690     * determine on the next iteration which should be B services.
691     */
692    int mNumServiceProcs = 0;
693    int mNewNumServiceProcs = 0;
694
695    /**
696     * System monitoring: number of processes that died since the last
697     * N procs were started.
698     */
699    int[] mProcDeaths = new int[20];
700
701    /**
702     * This is set if we had to do a delayed dexopt of an app before launching
703     * it, to increasing the ANR timeouts in that case.
704     */
705    boolean mDidDexOpt;
706
707    String mDebugApp = null;
708    boolean mWaitForDebugger = false;
709    boolean mDebugTransient = false;
710    String mOrigDebugApp = null;
711    boolean mOrigWaitForDebugger = false;
712    boolean mAlwaysFinishActivities = false;
713    IActivityController mController = null;
714    String mProfileApp = null;
715    ProcessRecord mProfileProc = null;
716    String mProfileFile;
717    ParcelFileDescriptor mProfileFd;
718    int mProfileType = 0;
719    boolean mAutoStopProfiler = false;
720    String mOpenGlTraceApp = null;
721
722    static class ProcessChangeItem {
723        static final int CHANGE_ACTIVITIES = 1<<0;
724        static final int CHANGE_IMPORTANCE= 1<<1;
725        int changes;
726        int uid;
727        int pid;
728        int importance;
729        boolean foregroundActivities;
730    }
731
732    final RemoteCallbackList<IProcessObserver> mProcessObservers
733            = new RemoteCallbackList<IProcessObserver>();
734    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
735
736    final ArrayList<ProcessChangeItem> mPendingProcessChanges
737            = new ArrayList<ProcessChangeItem>();
738    final ArrayList<ProcessChangeItem> mAvailProcessChanges
739            = new ArrayList<ProcessChangeItem>();
740
741    /**
742     * Callback of last caller to {@link #requestPss}.
743     */
744    Runnable mRequestPssCallback;
745
746    /**
747     * Remaining processes for which we are waiting results from the last
748     * call to {@link #requestPss}.
749     */
750    final ArrayList<ProcessRecord> mRequestPssList
751            = new ArrayList<ProcessRecord>();
752
753    /**
754     * Runtime statistics collection thread.  This object's lock is used to
755     * protect all related state.
756     */
757    final Thread mProcessStatsThread;
758
759    /**
760     * Used to collect process stats when showing not responding dialog.
761     * Protected by mProcessStatsThread.
762     */
763    final ProcessStats mProcessStats = new ProcessStats(
764            MONITOR_THREAD_CPU_USAGE);
765    final AtomicLong mLastCpuTime = new AtomicLong(0);
766    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
767
768    long mLastWriteTime = 0;
769
770    /**
771     * Set to true after the system has finished booting.
772     */
773    boolean mBooted = false;
774
775    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
776    int mProcessLimitOverride = -1;
777
778    WindowManagerService mWindowManager;
779
780    static ActivityManagerService mSelf;
781    static ActivityThread mSystemThread;
782
783    private int mCurrentUserId;
784    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
785    private UserManager mUserManager;
786
787    private final class AppDeathRecipient implements IBinder.DeathRecipient {
788        final ProcessRecord mApp;
789        final int mPid;
790        final IApplicationThread mAppThread;
791
792        AppDeathRecipient(ProcessRecord app, int pid,
793                IApplicationThread thread) {
794            if (localLOGV) Slog.v(
795                TAG, "New death recipient " + this
796                + " for thread " + thread.asBinder());
797            mApp = app;
798            mPid = pid;
799            mAppThread = thread;
800        }
801
802        public void binderDied() {
803            if (localLOGV) Slog.v(
804                TAG, "Death received in " + this
805                + " for thread " + mAppThread.asBinder());
806            synchronized(ActivityManagerService.this) {
807                appDiedLocked(mApp, mPid, mAppThread);
808            }
809        }
810    }
811
812    static final int SHOW_ERROR_MSG = 1;
813    static final int SHOW_NOT_RESPONDING_MSG = 2;
814    static final int SHOW_FACTORY_ERROR_MSG = 3;
815    static final int UPDATE_CONFIGURATION_MSG = 4;
816    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
817    static final int WAIT_FOR_DEBUGGER_MSG = 6;
818    static final int SERVICE_TIMEOUT_MSG = 12;
819    static final int UPDATE_TIME_ZONE = 13;
820    static final int SHOW_UID_ERROR_MSG = 14;
821    static final int IM_FEELING_LUCKY_MSG = 15;
822    static final int PROC_START_TIMEOUT_MSG = 20;
823    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
824    static final int KILL_APPLICATION_MSG = 22;
825    static final int FINALIZE_PENDING_INTENT_MSG = 23;
826    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
827    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
828    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
829    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
830    static final int CLEAR_DNS_CACHE = 28;
831    static final int UPDATE_HTTP_PROXY = 29;
832    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
833    static final int DISPATCH_PROCESSES_CHANGED = 31;
834    static final int DISPATCH_PROCESS_DIED = 32;
835    static final int REPORT_MEM_USAGE = 33;
836
837    static final int FIRST_ACTIVITY_STACK_MSG = 100;
838    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
839    static final int FIRST_COMPAT_MODE_MSG = 300;
840
841    AlertDialog mUidAlert;
842    CompatModeDialog mCompatModeDialog;
843    long mLastMemUsageReportTime = 0;
844
845    final Handler mHandler = new Handler() {
846        //public Handler() {
847        //    if (localLOGV) Slog.v(TAG, "Handler started!");
848        //}
849
850        public void handleMessage(Message msg) {
851            switch (msg.what) {
852            case SHOW_ERROR_MSG: {
853                HashMap data = (HashMap) msg.obj;
854                synchronized (ActivityManagerService.this) {
855                    ProcessRecord proc = (ProcessRecord)data.get("app");
856                    if (proc != null && proc.crashDialog != null) {
857                        Slog.e(TAG, "App already has crash dialog: " + proc);
858                        return;
859                    }
860                    AppErrorResult res = (AppErrorResult) data.get("result");
861                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
862                        Dialog d = new AppErrorDialog(mContext, res, proc);
863                        d.show();
864                        proc.crashDialog = d;
865                    } else {
866                        // The device is asleep, so just pretend that the user
867                        // saw a crash dialog and hit "force quit".
868                        res.set(0);
869                    }
870                }
871
872                ensureBootCompleted();
873            } break;
874            case SHOW_NOT_RESPONDING_MSG: {
875                synchronized (ActivityManagerService.this) {
876                    HashMap data = (HashMap) msg.obj;
877                    ProcessRecord proc = (ProcessRecord)data.get("app");
878                    if (proc != null && proc.anrDialog != null) {
879                        Slog.e(TAG, "App already has anr dialog: " + proc);
880                        return;
881                    }
882
883                    Intent intent = new Intent("android.intent.action.ANR");
884                    if (!mProcessesReady) {
885                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
886                                | Intent.FLAG_RECEIVER_FOREGROUND);
887                    }
888                    broadcastIntentLocked(null, null, intent,
889                            null, null, 0, null, null, null,
890                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
891
892                    if (mShowDialogs) {
893                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
894                                mContext, proc, (ActivityRecord)data.get("activity"));
895                        d.show();
896                        proc.anrDialog = d;
897                    } else {
898                        // Just kill the app if there is no dialog to be shown.
899                        killAppAtUsersRequest(proc, null);
900                    }
901                }
902
903                ensureBootCompleted();
904            } break;
905            case SHOW_STRICT_MODE_VIOLATION_MSG: {
906                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907                synchronized (ActivityManagerService.this) {
908                    ProcessRecord proc = (ProcessRecord) data.get("app");
909                    if (proc == null) {
910                        Slog.e(TAG, "App not found when showing strict mode dialog.");
911                        break;
912                    }
913                    if (proc.crashDialog != null) {
914                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
915                        return;
916                    }
917                    AppErrorResult res = (AppErrorResult) data.get("result");
918                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
919                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920                        d.show();
921                        proc.crashDialog = d;
922                    } else {
923                        // The device is asleep, so just pretend that the user
924                        // saw a crash dialog and hit "force quit".
925                        res.set(0);
926                    }
927                }
928                ensureBootCompleted();
929            } break;
930            case SHOW_FACTORY_ERROR_MSG: {
931                Dialog d = new FactoryErrorDialog(
932                    mContext, msg.getData().getCharSequence("msg"));
933                d.show();
934                ensureBootCompleted();
935            } break;
936            case UPDATE_CONFIGURATION_MSG: {
937                final ContentResolver resolver = mContext.getContentResolver();
938                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939            } break;
940            case GC_BACKGROUND_PROCESSES_MSG: {
941                synchronized (ActivityManagerService.this) {
942                    performAppGcsIfAppropriateLocked();
943                }
944            } break;
945            case WAIT_FOR_DEBUGGER_MSG: {
946                synchronized (ActivityManagerService.this) {
947                    ProcessRecord app = (ProcessRecord)msg.obj;
948                    if (msg.arg1 != 0) {
949                        if (!app.waitedForDebugger) {
950                            Dialog d = new AppWaitingForDebuggerDialog(
951                                    ActivityManagerService.this,
952                                    mContext, app);
953                            app.waitDialog = d;
954                            app.waitedForDebugger = true;
955                            d.show();
956                        }
957                    } else {
958                        if (app.waitDialog != null) {
959                            app.waitDialog.dismiss();
960                            app.waitDialog = null;
961                        }
962                    }
963                }
964            } break;
965            case SERVICE_TIMEOUT_MSG: {
966                if (mDidDexOpt) {
967                    mDidDexOpt = false;
968                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
969                    nmsg.obj = msg.obj;
970                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
971                    return;
972                }
973                mServices.serviceTimeout((ProcessRecord)msg.obj);
974            } break;
975            case UPDATE_TIME_ZONE: {
976                synchronized (ActivityManagerService.this) {
977                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
978                        ProcessRecord r = mLruProcesses.get(i);
979                        if (r.thread != null) {
980                            try {
981                                r.thread.updateTimeZone();
982                            } catch (RemoteException ex) {
983                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
984                            }
985                        }
986                    }
987                }
988            } break;
989            case CLEAR_DNS_CACHE: {
990                synchronized (ActivityManagerService.this) {
991                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
992                        ProcessRecord r = mLruProcesses.get(i);
993                        if (r.thread != null) {
994                            try {
995                                r.thread.clearDnsCache();
996                            } catch (RemoteException ex) {
997                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
998                            }
999                        }
1000                    }
1001                }
1002            } break;
1003            case UPDATE_HTTP_PROXY: {
1004                ProxyProperties proxy = (ProxyProperties)msg.obj;
1005                String host = "";
1006                String port = "";
1007                String exclList = "";
1008                if (proxy != null) {
1009                    host = proxy.getHost();
1010                    port = Integer.toString(proxy.getPort());
1011                    exclList = proxy.getExclusionList();
1012                }
1013                synchronized (ActivityManagerService.this) {
1014                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1015                        ProcessRecord r = mLruProcesses.get(i);
1016                        if (r.thread != null) {
1017                            try {
1018                                r.thread.setHttpProxy(host, port, exclList);
1019                            } catch (RemoteException ex) {
1020                                Slog.w(TAG, "Failed to update http proxy for: " +
1021                                        r.info.processName);
1022                            }
1023                        }
1024                    }
1025                }
1026            } break;
1027            case SHOW_UID_ERROR_MSG: {
1028                String title = "System UIDs Inconsistent";
1029                String text = "UIDs on the system are inconsistent, you need to wipe your"
1030                        + " data partition or your device will be unstable.";
1031                Log.e(TAG, title + ": " + text);
1032                if (mShowDialogs) {
1033                    // XXX This is a temporary dialog, no need to localize.
1034                    AlertDialog d = new BaseErrorDialog(mContext);
1035                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1036                    d.setCancelable(false);
1037                    d.setTitle(title);
1038                    d.setMessage(text);
1039                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1040                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1041                    mUidAlert = d;
1042                    d.show();
1043                }
1044            } break;
1045            case IM_FEELING_LUCKY_MSG: {
1046                if (mUidAlert != null) {
1047                    mUidAlert.dismiss();
1048                    mUidAlert = null;
1049                }
1050            } break;
1051            case PROC_START_TIMEOUT_MSG: {
1052                if (mDidDexOpt) {
1053                    mDidDexOpt = false;
1054                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1055                    nmsg.obj = msg.obj;
1056                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1057                    return;
1058                }
1059                ProcessRecord app = (ProcessRecord)msg.obj;
1060                synchronized (ActivityManagerService.this) {
1061                    processStartTimedOutLocked(app);
1062                }
1063            } break;
1064            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1065                synchronized (ActivityManagerService.this) {
1066                    doPendingActivityLaunchesLocked(true);
1067                }
1068            } break;
1069            case KILL_APPLICATION_MSG: {
1070                synchronized (ActivityManagerService.this) {
1071                    int uid = msg.arg1;
1072                    boolean restart = (msg.arg2 == 1);
1073                    String pkg = (String) msg.obj;
1074                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1075                            UserId.getUserId(uid));
1076                }
1077            } break;
1078            case FINALIZE_PENDING_INTENT_MSG: {
1079                ((PendingIntentRecord)msg.obj).completeFinalize();
1080            } break;
1081            case POST_HEAVY_NOTIFICATION_MSG: {
1082                INotificationManager inm = NotificationManager.getService();
1083                if (inm == null) {
1084                    return;
1085                }
1086
1087                ActivityRecord root = (ActivityRecord)msg.obj;
1088                ProcessRecord process = root.app;
1089                if (process == null) {
1090                    return;
1091                }
1092
1093                try {
1094                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1095                    String text = mContext.getString(R.string.heavy_weight_notification,
1096                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1097                    Notification notification = new Notification();
1098                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1099                    notification.when = 0;
1100                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1101                    notification.tickerText = text;
1102                    notification.defaults = 0; // please be quiet
1103                    notification.sound = null;
1104                    notification.vibrate = null;
1105                    notification.setLatestEventInfo(context, text,
1106                            mContext.getText(R.string.heavy_weight_notification_detail),
1107                            PendingIntent.getActivity(mContext, 0, root.intent,
1108                                    PendingIntent.FLAG_CANCEL_CURRENT));
1109
1110                    try {
1111                        int[] outId = new int[1];
1112                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1113                                notification, outId);
1114                    } catch (RuntimeException e) {
1115                        Slog.w(ActivityManagerService.TAG,
1116                                "Error showing notification for heavy-weight app", e);
1117                    } catch (RemoteException e) {
1118                    }
1119                } catch (NameNotFoundException e) {
1120                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1121                }
1122            } break;
1123            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1124                INotificationManager inm = NotificationManager.getService();
1125                if (inm == null) {
1126                    return;
1127                }
1128                try {
1129                    inm.cancelNotification("android",
1130                            R.string.heavy_weight_notification);
1131                } catch (RuntimeException e) {
1132                    Slog.w(ActivityManagerService.TAG,
1133                            "Error canceling notification for service", e);
1134                } catch (RemoteException e) {
1135                }
1136            } break;
1137            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1138                synchronized (ActivityManagerService.this) {
1139                    checkExcessivePowerUsageLocked(true);
1140                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1141                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1142                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1143                }
1144            } break;
1145            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    ActivityRecord ar = (ActivityRecord)msg.obj;
1148                    if (mCompatModeDialog != null) {
1149                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1150                                ar.info.applicationInfo.packageName)) {
1151                            return;
1152                        }
1153                        mCompatModeDialog.dismiss();
1154                        mCompatModeDialog = null;
1155                    }
1156                    if (ar != null && false) {
1157                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1158                                ar.packageName)) {
1159                            int mode = mCompatModePackages.computeCompatModeLocked(
1160                                    ar.info.applicationInfo);
1161                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1162                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1163                                mCompatModeDialog = new CompatModeDialog(
1164                                        ActivityManagerService.this, mContext,
1165                                        ar.info.applicationInfo);
1166                                mCompatModeDialog.show();
1167                            }
1168                        }
1169                    }
1170                }
1171                break;
1172            }
1173            case DISPATCH_PROCESSES_CHANGED: {
1174                dispatchProcessesChanged();
1175                break;
1176            }
1177            case DISPATCH_PROCESS_DIED: {
1178                final int pid = msg.arg1;
1179                final int uid = msg.arg2;
1180                dispatchProcessDied(pid, uid);
1181                break;
1182            }
1183            case REPORT_MEM_USAGE: {
1184                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1185                if (!isDebuggable) {
1186                    return;
1187                }
1188                synchronized (ActivityManagerService.this) {
1189                    long now = SystemClock.uptimeMillis();
1190                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1191                        // Don't report more than every 5 minutes to somewhat
1192                        // avoid spamming.
1193                        return;
1194                    }
1195                    mLastMemUsageReportTime = now;
1196                }
1197                Thread thread = new Thread() {
1198                    @Override public void run() {
1199                        StringBuilder dropBuilder = new StringBuilder(1024);
1200                        StringBuilder logBuilder = new StringBuilder(1024);
1201                        StringWriter oomSw = new StringWriter();
1202                        PrintWriter oomPw = new PrintWriter(oomSw);
1203                        StringWriter catSw = new StringWriter();
1204                        PrintWriter catPw = new PrintWriter(catSw);
1205                        String[] emptyArgs = new String[] { };
1206                        StringBuilder tag = new StringBuilder(128);
1207                        StringBuilder stack = new StringBuilder(128);
1208                        tag.append("Low on memory -- ");
1209                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1210                                tag, stack);
1211                        dropBuilder.append(stack);
1212                        dropBuilder.append('\n');
1213                        dropBuilder.append('\n');
1214                        String oomString = oomSw.toString();
1215                        dropBuilder.append(oomString);
1216                        dropBuilder.append('\n');
1217                        logBuilder.append(oomString);
1218                        try {
1219                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1220                                    "procrank", });
1221                            final InputStreamReader converter = new InputStreamReader(
1222                                    proc.getInputStream());
1223                            BufferedReader in = new BufferedReader(converter);
1224                            String line;
1225                            while (true) {
1226                                line = in.readLine();
1227                                if (line == null) {
1228                                    break;
1229                                }
1230                                if (line.length() > 0) {
1231                                    logBuilder.append(line);
1232                                    logBuilder.append('\n');
1233                                }
1234                                dropBuilder.append(line);
1235                                dropBuilder.append('\n');
1236                            }
1237                            converter.close();
1238                        } catch (IOException e) {
1239                        }
1240                        synchronized (ActivityManagerService.this) {
1241                            catPw.println();
1242                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1243                            catPw.println();
1244                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1245                                    false, false, null);
1246                            catPw.println();
1247                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1248                        }
1249                        dropBuilder.append(catSw.toString());
1250                        addErrorToDropBox("lowmem", null, "system_server", null,
1251                                null, tag.toString(), dropBuilder.toString(), null, null);
1252                        Slog.i(TAG, logBuilder.toString());
1253                        synchronized (ActivityManagerService.this) {
1254                            long now = SystemClock.uptimeMillis();
1255                            if (mLastMemUsageReportTime < now) {
1256                                mLastMemUsageReportTime = now;
1257                            }
1258                        }
1259                    }
1260                };
1261                thread.start();
1262                break;
1263            }
1264            }
1265        }
1266    };
1267
1268    public static void setSystemProcess() {
1269        try {
1270            ActivityManagerService m = mSelf;
1271
1272            ServiceManager.addService("activity", m, true);
1273            ServiceManager.addService("meminfo", new MemBinder(m));
1274            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1275            ServiceManager.addService("dbinfo", new DbBinder(m));
1276            if (MONITOR_CPU_USAGE) {
1277                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1278            }
1279            ServiceManager.addService("permission", new PermissionController(m));
1280
1281            ApplicationInfo info =
1282                mSelf.mContext.getPackageManager().getApplicationInfo(
1283                            "android", STOCK_PM_FLAGS);
1284            mSystemThread.installSystemApplicationInfo(info);
1285
1286            synchronized (mSelf) {
1287                ProcessRecord app = mSelf.newProcessRecordLocked(
1288                        mSystemThread.getApplicationThread(), info,
1289                        info.processName, false);
1290                app.persistent = true;
1291                app.pid = MY_PID;
1292                app.maxAdj = ProcessList.SYSTEM_ADJ;
1293                mSelf.mProcessNames.put(app.processName, app.uid, app);
1294                synchronized (mSelf.mPidsSelfLocked) {
1295                    mSelf.mPidsSelfLocked.put(app.pid, app);
1296                }
1297                mSelf.updateLruProcessLocked(app, true, true);
1298            }
1299        } catch (PackageManager.NameNotFoundException e) {
1300            throw new RuntimeException(
1301                    "Unable to find android system package", e);
1302        }
1303    }
1304
1305    public void setWindowManager(WindowManagerService wm) {
1306        mWindowManager = wm;
1307    }
1308
1309    public static final Context main(int factoryTest) {
1310        AThread thr = new AThread();
1311        thr.start();
1312
1313        synchronized (thr) {
1314            while (thr.mService == null) {
1315                try {
1316                    thr.wait();
1317                } catch (InterruptedException e) {
1318                }
1319            }
1320        }
1321
1322        ActivityManagerService m = thr.mService;
1323        mSelf = m;
1324        ActivityThread at = ActivityThread.systemMain();
1325        mSystemThread = at;
1326        Context context = at.getSystemContext();
1327        context.setTheme(android.R.style.Theme_Holo);
1328        m.mContext = context;
1329        m.mFactoryTest = factoryTest;
1330        m.mMainStack = new ActivityStack(m, context, true);
1331
1332        m.mBatteryStatsService.publish(context);
1333        m.mUsageStatsService.publish(context);
1334
1335        synchronized (thr) {
1336            thr.mReady = true;
1337            thr.notifyAll();
1338        }
1339
1340        m.startRunning(null, null, null, null);
1341
1342        return context;
1343    }
1344
1345    public static ActivityManagerService self() {
1346        return mSelf;
1347    }
1348
1349    static class AThread extends Thread {
1350        ActivityManagerService mService;
1351        boolean mReady = false;
1352
1353        public AThread() {
1354            super("ActivityManager");
1355        }
1356
1357        public void run() {
1358            Looper.prepare();
1359
1360            android.os.Process.setThreadPriority(
1361                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1362            android.os.Process.setCanSelfBackground(false);
1363
1364            ActivityManagerService m = new ActivityManagerService();
1365
1366            synchronized (this) {
1367                mService = m;
1368                notifyAll();
1369            }
1370
1371            synchronized (this) {
1372                while (!mReady) {
1373                    try {
1374                        wait();
1375                    } catch (InterruptedException e) {
1376                    }
1377                }
1378            }
1379
1380            // For debug builds, log event loop stalls to dropbox for analysis.
1381            if (StrictMode.conditionallyEnableDebugLogging()) {
1382                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1383            }
1384
1385            Looper.loop();
1386        }
1387    }
1388
1389    static class MemBinder extends Binder {
1390        ActivityManagerService mActivityManagerService;
1391        MemBinder(ActivityManagerService activityManagerService) {
1392            mActivityManagerService = activityManagerService;
1393        }
1394
1395        @Override
1396        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1397            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1398                    != PackageManager.PERMISSION_GRANTED) {
1399                pw.println("Permission Denial: can't dump meminfo from from pid="
1400                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1401                        + " without permission " + android.Manifest.permission.DUMP);
1402                return;
1403            }
1404
1405            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1406                    false, null, null, null);
1407        }
1408    }
1409
1410    static class GraphicsBinder extends Binder {
1411        ActivityManagerService mActivityManagerService;
1412        GraphicsBinder(ActivityManagerService activityManagerService) {
1413            mActivityManagerService = activityManagerService;
1414        }
1415
1416        @Override
1417        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1418            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1419                    != PackageManager.PERMISSION_GRANTED) {
1420                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1421                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1422                        + " without permission " + android.Manifest.permission.DUMP);
1423                return;
1424            }
1425
1426            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1427        }
1428    }
1429
1430    static class DbBinder extends Binder {
1431        ActivityManagerService mActivityManagerService;
1432        DbBinder(ActivityManagerService activityManagerService) {
1433            mActivityManagerService = activityManagerService;
1434        }
1435
1436        @Override
1437        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1438            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1439                    != PackageManager.PERMISSION_GRANTED) {
1440                pw.println("Permission Denial: can't dump dbinfo from from pid="
1441                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1442                        + " without permission " + android.Manifest.permission.DUMP);
1443                return;
1444            }
1445
1446            mActivityManagerService.dumpDbInfo(fd, pw, args);
1447        }
1448    }
1449
1450    static class CpuBinder extends Binder {
1451        ActivityManagerService mActivityManagerService;
1452        CpuBinder(ActivityManagerService activityManagerService) {
1453            mActivityManagerService = activityManagerService;
1454        }
1455
1456        @Override
1457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1459                    != PackageManager.PERMISSION_GRANTED) {
1460                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1462                        + " without permission " + android.Manifest.permission.DUMP);
1463                return;
1464            }
1465
1466            synchronized (mActivityManagerService.mProcessStatsThread) {
1467                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1468                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1469                        SystemClock.uptimeMillis()));
1470            }
1471        }
1472    }
1473
1474    private ActivityManagerService() {
1475        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1476
1477        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1478        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1479        mBroadcastQueues[0] = mFgBroadcastQueue;
1480        mBroadcastQueues[1] = mBgBroadcastQueue;
1481
1482        mServices = new ActiveServices(this);
1483
1484        File dataDir = Environment.getDataDirectory();
1485        File systemDir = new File(dataDir, "system");
1486        systemDir.mkdirs();
1487        mBatteryStatsService = new BatteryStatsService(new File(
1488                systemDir, "batterystats.bin").toString());
1489        mBatteryStatsService.getActiveStatistics().readLocked();
1490        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1491        mOnBattery = DEBUG_POWER ? true
1492                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1493        mBatteryStatsService.getActiveStatistics().setCallback(this);
1494
1495        mUsageStatsService = new UsageStatsService(new File(
1496                systemDir, "usagestats").toString());
1497        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1498
1499        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1500            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1501
1502        mConfiguration.setToDefaults();
1503        mConfiguration.locale = Locale.getDefault();
1504        mConfigurationSeq = mConfiguration.seq = 1;
1505        mProcessStats.init();
1506
1507        mCompatModePackages = new CompatModePackages(this, systemDir);
1508
1509        // Add ourself to the Watchdog monitors.
1510        Watchdog.getInstance().addMonitor(this);
1511
1512        mProcessStatsThread = new Thread("ProcessStats") {
1513            public void run() {
1514                while (true) {
1515                    try {
1516                        try {
1517                            synchronized(this) {
1518                                final long now = SystemClock.uptimeMillis();
1519                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1520                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1521                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1522                                //        + ", write delay=" + nextWriteDelay);
1523                                if (nextWriteDelay < nextCpuDelay) {
1524                                    nextCpuDelay = nextWriteDelay;
1525                                }
1526                                if (nextCpuDelay > 0) {
1527                                    mProcessStatsMutexFree.set(true);
1528                                    this.wait(nextCpuDelay);
1529                                }
1530                            }
1531                        } catch (InterruptedException e) {
1532                        }
1533                        updateCpuStatsNow();
1534                    } catch (Exception e) {
1535                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1536                    }
1537                }
1538            }
1539        };
1540        mProcessStatsThread.start();
1541    }
1542
1543    @Override
1544    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1545            throws RemoteException {
1546        if (code == SYSPROPS_TRANSACTION) {
1547            // We need to tell all apps about the system property change.
1548            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1549            synchronized(this) {
1550                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1551                    final int NA = apps.size();
1552                    for (int ia=0; ia<NA; ia++) {
1553                        ProcessRecord app = apps.valueAt(ia);
1554                        if (app.thread != null) {
1555                            procs.add(app.thread.asBinder());
1556                        }
1557                    }
1558                }
1559            }
1560
1561            int N = procs.size();
1562            for (int i=0; i<N; i++) {
1563                Parcel data2 = Parcel.obtain();
1564                try {
1565                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1566                } catch (RemoteException e) {
1567                }
1568                data2.recycle();
1569            }
1570        }
1571        try {
1572            return super.onTransact(code, data, reply, flags);
1573        } catch (RuntimeException e) {
1574            // The activity manager only throws security exceptions, so let's
1575            // log all others.
1576            if (!(e instanceof SecurityException)) {
1577                Slog.e(TAG, "Activity Manager Crash", e);
1578            }
1579            throw e;
1580        }
1581    }
1582
1583    void updateCpuStats() {
1584        final long now = SystemClock.uptimeMillis();
1585        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1586            return;
1587        }
1588        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1589            synchronized (mProcessStatsThread) {
1590                mProcessStatsThread.notify();
1591            }
1592        }
1593    }
1594
1595    void updateCpuStatsNow() {
1596        synchronized (mProcessStatsThread) {
1597            mProcessStatsMutexFree.set(false);
1598            final long now = SystemClock.uptimeMillis();
1599            boolean haveNewCpuStats = false;
1600
1601            if (MONITOR_CPU_USAGE &&
1602                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1603                mLastCpuTime.set(now);
1604                haveNewCpuStats = true;
1605                mProcessStats.update();
1606                //Slog.i(TAG, mProcessStats.printCurrentState());
1607                //Slog.i(TAG, "Total CPU usage: "
1608                //        + mProcessStats.getTotalCpuPercent() + "%");
1609
1610                // Slog the cpu usage if the property is set.
1611                if ("true".equals(SystemProperties.get("events.cpu"))) {
1612                    int user = mProcessStats.getLastUserTime();
1613                    int system = mProcessStats.getLastSystemTime();
1614                    int iowait = mProcessStats.getLastIoWaitTime();
1615                    int irq = mProcessStats.getLastIrqTime();
1616                    int softIrq = mProcessStats.getLastSoftIrqTime();
1617                    int idle = mProcessStats.getLastIdleTime();
1618
1619                    int total = user + system + iowait + irq + softIrq + idle;
1620                    if (total == 0) total = 1;
1621
1622                    EventLog.writeEvent(EventLogTags.CPU,
1623                            ((user+system+iowait+irq+softIrq) * 100) / total,
1624                            (user * 100) / total,
1625                            (system * 100) / total,
1626                            (iowait * 100) / total,
1627                            (irq * 100) / total,
1628                            (softIrq * 100) / total);
1629                }
1630            }
1631
1632            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1633            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1634            synchronized(bstats) {
1635                synchronized(mPidsSelfLocked) {
1636                    if (haveNewCpuStats) {
1637                        if (mOnBattery) {
1638                            int perc = bstats.startAddingCpuLocked();
1639                            int totalUTime = 0;
1640                            int totalSTime = 0;
1641                            final int N = mProcessStats.countStats();
1642                            for (int i=0; i<N; i++) {
1643                                ProcessStats.Stats st = mProcessStats.getStats(i);
1644                                if (!st.working) {
1645                                    continue;
1646                                }
1647                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1648                                int otherUTime = (st.rel_utime*perc)/100;
1649                                int otherSTime = (st.rel_stime*perc)/100;
1650                                totalUTime += otherUTime;
1651                                totalSTime += otherSTime;
1652                                if (pr != null) {
1653                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1654                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1655                                            st.rel_stime-otherSTime);
1656                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1657                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1658                                } else {
1659                                    BatteryStatsImpl.Uid.Proc ps =
1660                                            bstats.getProcessStatsLocked(st.name, st.pid);
1661                                    if (ps != null) {
1662                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1663                                                st.rel_stime-otherSTime);
1664                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1665                                    }
1666                                }
1667                            }
1668                            bstats.finishAddingCpuLocked(perc, totalUTime,
1669                                    totalSTime, cpuSpeedTimes);
1670                        }
1671                    }
1672                }
1673
1674                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1675                    mLastWriteTime = now;
1676                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1677                }
1678            }
1679        }
1680    }
1681
1682    @Override
1683    public void batteryNeedsCpuUpdate() {
1684        updateCpuStatsNow();
1685    }
1686
1687    @Override
1688    public void batteryPowerChanged(boolean onBattery) {
1689        // When plugging in, update the CPU stats first before changing
1690        // the plug state.
1691        updateCpuStatsNow();
1692        synchronized (this) {
1693            synchronized(mPidsSelfLocked) {
1694                mOnBattery = DEBUG_POWER ? true : onBattery;
1695            }
1696        }
1697    }
1698
1699    /**
1700     * Initialize the application bind args. These are passed to each
1701     * process when the bindApplication() IPC is sent to the process. They're
1702     * lazily setup to make sure the services are running when they're asked for.
1703     */
1704    private HashMap<String, IBinder> getCommonServicesLocked() {
1705        if (mAppBindArgs == null) {
1706            mAppBindArgs = new HashMap<String, IBinder>();
1707
1708            // Setup the application init args
1709            mAppBindArgs.put("package", ServiceManager.getService("package"));
1710            mAppBindArgs.put("window", ServiceManager.getService("window"));
1711            mAppBindArgs.put(Context.ALARM_SERVICE,
1712                    ServiceManager.getService(Context.ALARM_SERVICE));
1713        }
1714        return mAppBindArgs;
1715    }
1716
1717    final void setFocusedActivityLocked(ActivityRecord r) {
1718        if (mFocusedActivity != r) {
1719            mFocusedActivity = r;
1720            if (r != null) {
1721                mWindowManager.setFocusedApp(r.appToken, true);
1722            }
1723        }
1724    }
1725
1726    private final void updateLruProcessInternalLocked(ProcessRecord app,
1727            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1728        // put it on the LRU to keep track of when it should be exited.
1729        int lrui = mLruProcesses.indexOf(app);
1730        if (lrui >= 0) mLruProcesses.remove(lrui);
1731
1732        int i = mLruProcesses.size()-1;
1733        int skipTop = 0;
1734
1735        app.lruSeq = mLruSeq;
1736
1737        // compute the new weight for this process.
1738        if (updateActivityTime) {
1739            app.lastActivityTime = SystemClock.uptimeMillis();
1740        }
1741        if (app.activities.size() > 0) {
1742            // If this process has activities, we more strongly want to keep
1743            // it around.
1744            app.lruWeight = app.lastActivityTime;
1745        } else if (app.pubProviders.size() > 0) {
1746            // If this process contains content providers, we want to keep
1747            // it a little more strongly.
1748            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1749            // Also don't let it kick out the first few "real" hidden processes.
1750            skipTop = ProcessList.MIN_HIDDEN_APPS;
1751        } else {
1752            // If this process doesn't have activities, we less strongly
1753            // want to keep it around, and generally want to avoid getting
1754            // in front of any very recently used activities.
1755            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1756            // Also don't let it kick out the first few "real" hidden processes.
1757            skipTop = ProcessList.MIN_HIDDEN_APPS;
1758        }
1759
1760        while (i >= 0) {
1761            ProcessRecord p = mLruProcesses.get(i);
1762            // If this app shouldn't be in front of the first N background
1763            // apps, then skip over that many that are currently hidden.
1764            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1765                skipTop--;
1766            }
1767            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1768                mLruProcesses.add(i+1, app);
1769                break;
1770            }
1771            i--;
1772        }
1773        if (i < 0) {
1774            mLruProcesses.add(0, app);
1775        }
1776
1777        // If the app is currently using a content provider or service,
1778        // bump those processes as well.
1779        if (app.connections.size() > 0) {
1780            for (ConnectionRecord cr : app.connections) {
1781                if (cr.binding != null && cr.binding.service != null
1782                        && cr.binding.service.app != null
1783                        && cr.binding.service.app.lruSeq != mLruSeq) {
1784                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1785                            updateActivityTime, i+1);
1786                }
1787            }
1788        }
1789        for (int j=app.conProviders.size()-1; j>=0; j--) {
1790            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1791            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1792                updateLruProcessInternalLocked(cpr.proc, false,
1793                        updateActivityTime, i+1);
1794            }
1795        }
1796
1797        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1798        if (oomAdj) {
1799            updateOomAdjLocked();
1800        }
1801    }
1802
1803    final void updateLruProcessLocked(ProcessRecord app,
1804            boolean oomAdj, boolean updateActivityTime) {
1805        mLruSeq++;
1806        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1807    }
1808
1809    final ProcessRecord getProcessRecordLocked(
1810            String processName, int uid) {
1811        if (uid == Process.SYSTEM_UID) {
1812            // The system gets to run in any process.  If there are multiple
1813            // processes with the same uid, just pick the first (this
1814            // should never happen).
1815            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1816                    processName);
1817            if (procs == null) return null;
1818            final int N = procs.size();
1819            for (int i = 0; i < N; i++) {
1820                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1821            }
1822        }
1823        ProcessRecord proc = mProcessNames.get(processName, uid);
1824        return proc;
1825    }
1826
1827    void ensurePackageDexOpt(String packageName) {
1828        IPackageManager pm = AppGlobals.getPackageManager();
1829        try {
1830            if (pm.performDexOpt(packageName)) {
1831                mDidDexOpt = true;
1832            }
1833        } catch (RemoteException e) {
1834        }
1835    }
1836
1837    boolean isNextTransitionForward() {
1838        int transit = mWindowManager.getPendingAppTransition();
1839        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1840                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1841                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1842    }
1843
1844    final ProcessRecord startProcessLocked(String processName,
1845            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1846            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1847            boolean isolated) {
1848        ProcessRecord app;
1849        if (!isolated) {
1850            app = getProcessRecordLocked(processName, info.uid);
1851        } else {
1852            // If this is an isolated process, it can't re-use an existing process.
1853            app = null;
1854        }
1855        // We don't have to do anything more if:
1856        // (1) There is an existing application record; and
1857        // (2) The caller doesn't think it is dead, OR there is no thread
1858        //     object attached to it so we know it couldn't have crashed; and
1859        // (3) There is a pid assigned to it, so it is either starting or
1860        //     already running.
1861        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1862                + " app=" + app + " knownToBeDead=" + knownToBeDead
1863                + " thread=" + (app != null ? app.thread : null)
1864                + " pid=" + (app != null ? app.pid : -1));
1865        if (app != null && app.pid > 0) {
1866            if (!knownToBeDead || app.thread == null) {
1867                // We already have the app running, or are waiting for it to
1868                // come up (we have a pid but not yet its thread), so keep it.
1869                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1870                // If this is a new package in the process, add the package to the list
1871                app.addPackage(info.packageName);
1872                return app;
1873            } else {
1874                // An application record is attached to a previous process,
1875                // clean it up now.
1876                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1877                handleAppDiedLocked(app, true, true);
1878            }
1879        }
1880
1881        String hostingNameStr = hostingName != null
1882                ? hostingName.flattenToShortString() : null;
1883
1884        if (!isolated) {
1885            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1886                // If we are in the background, then check to see if this process
1887                // is bad.  If so, we will just silently fail.
1888                if (mBadProcesses.get(info.processName, info.uid) != null) {
1889                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1890                            + "/" + info.processName);
1891                    return null;
1892                }
1893            } else {
1894                // When the user is explicitly starting a process, then clear its
1895                // crash count so that we won't make it bad until they see at
1896                // least one crash dialog again, and make the process good again
1897                // if it had been bad.
1898                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1899                        + "/" + info.processName);
1900                mProcessCrashTimes.remove(info.processName, info.uid);
1901                if (mBadProcesses.get(info.processName, info.uid) != null) {
1902                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1903                            info.processName);
1904                    mBadProcesses.remove(info.processName, info.uid);
1905                    if (app != null) {
1906                        app.bad = false;
1907                    }
1908                }
1909            }
1910        }
1911
1912        if (app == null) {
1913            app = newProcessRecordLocked(null, info, processName, isolated);
1914            if (app == null) {
1915                Slog.w(TAG, "Failed making new process record for "
1916                        + processName + "/" + info.uid + " isolated=" + isolated);
1917                return null;
1918            }
1919            mProcessNames.put(processName, app.uid, app);
1920            if (isolated) {
1921                mIsolatedProcesses.put(app.uid, app);
1922            }
1923        } else {
1924            // If this is a new package in the process, add the package to the list
1925            app.addPackage(info.packageName);
1926        }
1927
1928        // If the system is not ready yet, then hold off on starting this
1929        // process until it is.
1930        if (!mProcessesReady
1931                && !isAllowedWhileBooting(info)
1932                && !allowWhileBooting) {
1933            if (!mProcessesOnHold.contains(app)) {
1934                mProcessesOnHold.add(app);
1935            }
1936            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1937            return app;
1938        }
1939
1940        startProcessLocked(app, hostingType, hostingNameStr);
1941        return (app.pid != 0) ? app : null;
1942    }
1943
1944    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1945        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1946    }
1947
1948    private final void startProcessLocked(ProcessRecord app,
1949            String hostingType, String hostingNameStr) {
1950        if (app.pid > 0 && app.pid != MY_PID) {
1951            synchronized (mPidsSelfLocked) {
1952                mPidsSelfLocked.remove(app.pid);
1953                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1954            }
1955            app.pid = 0;
1956        }
1957
1958        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1959                "startProcessLocked removing on hold: " + app);
1960        mProcessesOnHold.remove(app);
1961
1962        updateCpuStats();
1963
1964        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1965        mProcDeaths[0] = 0;
1966
1967        try {
1968            int uid = app.uid;
1969
1970            int[] gids = null;
1971            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1972            if (!app.isolated) {
1973                try {
1974                    final PackageManager pm = mContext.getPackageManager();
1975                    gids = pm.getPackageGids(app.info.packageName);
1976                    if (pm.checkPermission(
1977                            android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName)
1978                            == PERMISSION_GRANTED) {
1979                        if (Environment.isExternalStorageEmulated()) {
1980                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1981                        } else {
1982                            mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
1983                        }
1984                    }
1985                } catch (PackageManager.NameNotFoundException e) {
1986                    Slog.w(TAG, "Unable to retrieve gids", e);
1987                }
1988            }
1989            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1990                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1991                        && mTopComponent != null
1992                        && app.processName.equals(mTopComponent.getPackageName())) {
1993                    uid = 0;
1994                }
1995                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1996                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1997                    uid = 0;
1998                }
1999            }
2000            int debugFlags = 0;
2001            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2002                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2003                // Also turn on CheckJNI for debuggable apps. It's quite
2004                // awkward to turn on otherwise.
2005                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2006            }
2007            // Run the app in safe mode if its manifest requests so or the
2008            // system is booted in safe mode.
2009            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2010                Zygote.systemInSafeMode == true) {
2011                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2012            }
2013            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2014                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2015            }
2016            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2017                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2018            }
2019            if ("1".equals(SystemProperties.get("debug.assert"))) {
2020                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2021            }
2022
2023            // Start the process.  It will either succeed and return a result containing
2024            // the PID of the new process, or else throw a RuntimeException.
2025            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2026                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2027                    app.info.targetSdkVersion, null, null);
2028
2029            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2030            synchronized (bs) {
2031                if (bs.isOnBattery()) {
2032                    app.batteryStats.incStartsLocked();
2033                }
2034            }
2035
2036            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2037                    app.processName, hostingType,
2038                    hostingNameStr != null ? hostingNameStr : "");
2039
2040            if (app.persistent) {
2041                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2042            }
2043
2044            StringBuilder buf = mStringBuilder;
2045            buf.setLength(0);
2046            buf.append("Start proc ");
2047            buf.append(app.processName);
2048            buf.append(" for ");
2049            buf.append(hostingType);
2050            if (hostingNameStr != null) {
2051                buf.append(" ");
2052                buf.append(hostingNameStr);
2053            }
2054            buf.append(": pid=");
2055            buf.append(startResult.pid);
2056            buf.append(" uid=");
2057            buf.append(uid);
2058            buf.append(" gids={");
2059            if (gids != null) {
2060                for (int gi=0; gi<gids.length; gi++) {
2061                    if (gi != 0) buf.append(", ");
2062                    buf.append(gids[gi]);
2063
2064                }
2065            }
2066            buf.append("}");
2067            Slog.i(TAG, buf.toString());
2068            app.pid = startResult.pid;
2069            app.usingWrapper = startResult.usingWrapper;
2070            app.removed = false;
2071            synchronized (mPidsSelfLocked) {
2072                this.mPidsSelfLocked.put(startResult.pid, app);
2073                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2074                msg.obj = app;
2075                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2076                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2077            }
2078        } catch (RuntimeException e) {
2079            // XXX do better error recovery.
2080            app.pid = 0;
2081            Slog.e(TAG, "Failure starting process " + app.processName, e);
2082        }
2083    }
2084
2085    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2086        if (resumed) {
2087            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2088        } else {
2089            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2090        }
2091    }
2092
2093    boolean startHomeActivityLocked(int userId) {
2094        if (mHeadless) {
2095            // Added because none of the other calls to ensureBootCompleted seem to fire
2096            // when running headless.
2097            ensureBootCompleted();
2098            return false;
2099        }
2100
2101        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2102                && mTopAction == null) {
2103            // We are running in factory test mode, but unable to find
2104            // the factory test app, so just sit around displaying the
2105            // error message and don't try to start anything.
2106            return false;
2107        }
2108        Intent intent = new Intent(
2109            mTopAction,
2110            mTopData != null ? Uri.parse(mTopData) : null);
2111        intent.setComponent(mTopComponent);
2112        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2113            intent.addCategory(Intent.CATEGORY_HOME);
2114        }
2115        ActivityInfo aInfo =
2116            intent.resolveActivityInfo(mContext.getPackageManager(),
2117                    STOCK_PM_FLAGS);
2118        if (aInfo != null) {
2119            intent.setComponent(new ComponentName(
2120                    aInfo.applicationInfo.packageName, aInfo.name));
2121            // Don't do this if the home app is currently being
2122            // instrumented.
2123            aInfo = new ActivityInfo(aInfo);
2124            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2125            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2126                    aInfo.applicationInfo.uid);
2127            if (app == null || app.instrumentationClass == null) {
2128                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2129                mMainStack.startActivityLocked(null, intent, null, aInfo,
2130                        null, null, 0, 0, 0, 0, null, false, null);
2131            }
2132        }
2133
2134        return true;
2135    }
2136
2137    /**
2138     * Starts the "new version setup screen" if appropriate.
2139     */
2140    void startSetupActivityLocked() {
2141        // Only do this once per boot.
2142        if (mCheckedForSetup) {
2143            return;
2144        }
2145
2146        // We will show this screen if the current one is a different
2147        // version than the last one shown, and we are not running in
2148        // low-level factory test mode.
2149        final ContentResolver resolver = mContext.getContentResolver();
2150        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2151                Settings.Secure.getInt(resolver,
2152                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2153            mCheckedForSetup = true;
2154
2155            // See if we should be showing the platform update setup UI.
2156            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2157            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2158                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2159
2160            // We don't allow third party apps to replace this.
2161            ResolveInfo ri = null;
2162            for (int i=0; ris != null && i<ris.size(); i++) {
2163                if ((ris.get(i).activityInfo.applicationInfo.flags
2164                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2165                    ri = ris.get(i);
2166                    break;
2167                }
2168            }
2169
2170            if (ri != null) {
2171                String vers = ri.activityInfo.metaData != null
2172                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2173                        : null;
2174                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2175                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2176                            Intent.METADATA_SETUP_VERSION);
2177                }
2178                String lastVers = Settings.Secure.getString(
2179                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2180                if (vers != null && !vers.equals(lastVers)) {
2181                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2182                    intent.setComponent(new ComponentName(
2183                            ri.activityInfo.packageName, ri.activityInfo.name));
2184                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2185                            null, null, 0, 0, 0, 0, null, false, null);
2186                }
2187            }
2188        }
2189    }
2190
2191    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2192        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2193    }
2194
2195    void enforceNotIsolatedCaller(String caller) {
2196        if (UserId.isIsolated(Binder.getCallingUid())) {
2197            throw new SecurityException("Isolated process not allowed to call " + caller);
2198        }
2199    }
2200
2201    public int getFrontActivityScreenCompatMode() {
2202        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2203        synchronized (this) {
2204            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2205        }
2206    }
2207
2208    public void setFrontActivityScreenCompatMode(int mode) {
2209        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2210                "setFrontActivityScreenCompatMode");
2211        synchronized (this) {
2212            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2213        }
2214    }
2215
2216    public int getPackageScreenCompatMode(String packageName) {
2217        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2218        synchronized (this) {
2219            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2220        }
2221    }
2222
2223    public void setPackageScreenCompatMode(String packageName, int mode) {
2224        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2225                "setPackageScreenCompatMode");
2226        synchronized (this) {
2227            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2228        }
2229    }
2230
2231    public boolean getPackageAskScreenCompat(String packageName) {
2232        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2233        synchronized (this) {
2234            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2235        }
2236    }
2237
2238    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2240                "setPackageAskScreenCompat");
2241        synchronized (this) {
2242            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2243        }
2244    }
2245
2246    void reportResumedActivityLocked(ActivityRecord r) {
2247        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2248        updateUsageStats(r, true);
2249    }
2250
2251    private void dispatchProcessesChanged() {
2252        int N;
2253        synchronized (this) {
2254            N = mPendingProcessChanges.size();
2255            if (mActiveProcessChanges.length < N) {
2256                mActiveProcessChanges = new ProcessChangeItem[N];
2257            }
2258            mPendingProcessChanges.toArray(mActiveProcessChanges);
2259            mAvailProcessChanges.addAll(mPendingProcessChanges);
2260            mPendingProcessChanges.clear();
2261            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2262        }
2263        int i = mProcessObservers.beginBroadcast();
2264        while (i > 0) {
2265            i--;
2266            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2267            if (observer != null) {
2268                try {
2269                    for (int j=0; j<N; j++) {
2270                        ProcessChangeItem item = mActiveProcessChanges[j];
2271                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2272                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2273                                    + item.pid + " uid=" + item.uid + ": "
2274                                    + item.foregroundActivities);
2275                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2276                                    item.foregroundActivities);
2277                        }
2278                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2279                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2280                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2281                            observer.onImportanceChanged(item.pid, item.uid,
2282                                    item.importance);
2283                        }
2284                    }
2285                } catch (RemoteException e) {
2286                }
2287            }
2288        }
2289        mProcessObservers.finishBroadcast();
2290    }
2291
2292    private void dispatchProcessDied(int pid, int uid) {
2293        int i = mProcessObservers.beginBroadcast();
2294        while (i > 0) {
2295            i--;
2296            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2297            if (observer != null) {
2298                try {
2299                    observer.onProcessDied(pid, uid);
2300                } catch (RemoteException e) {
2301                }
2302            }
2303        }
2304        mProcessObservers.finishBroadcast();
2305    }
2306
2307    final void doPendingActivityLaunchesLocked(boolean doResume) {
2308        final int N = mPendingActivityLaunches.size();
2309        if (N <= 0) {
2310            return;
2311        }
2312        for (int i=0; i<N; i++) {
2313            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2314            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2315                    pal.startFlags, doResume && i == (N-1), null);
2316        }
2317        mPendingActivityLaunches.clear();
2318    }
2319
2320    public final int startActivity(IApplicationThread caller,
2321            Intent intent, String resolvedType, IBinder resultTo,
2322            String resultWho, int requestCode, int startFlags,
2323            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2324        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2325                startFlags, profileFile, profileFd, options, UserId.getCallingUserId());
2326    }
2327
2328    public final int startActivityAsUser(IApplicationThread caller,
2329            Intent intent, String resolvedType, IBinder resultTo,
2330            String resultWho, int requestCode, int startFlags,
2331            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2332        enforceNotIsolatedCaller("startActivity");
2333        if (userId != UserId.getCallingUserId()) {
2334            // Requesting a different user, make sure that they have the permission
2335            if (checkComponentPermission(
2336                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2337                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2338                    == PackageManager.PERMISSION_GRANTED) {
2339                // Translate to the current user id, if caller wasn't aware
2340                if (userId == UserId.USER_CURRENT) {
2341                    userId = mCurrentUserId;
2342                }
2343            } else {
2344                String msg = "Permission Denial: "
2345                        + "Request to startActivity as user " + userId
2346                        + " but is calling from user " + UserId.getCallingUserId()
2347                        + "; this requires "
2348                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2349                Slog.w(TAG, msg);
2350                throw new SecurityException(msg);
2351            }
2352        } else {
2353            if (intent.getCategories() != null
2354                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2355                // Requesting home, set the identity to the current user
2356                // HACK!
2357                userId = mCurrentUserId;
2358            } else {
2359                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2360                // the current user's userId
2361                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2362                    userId = 0;
2363                } else {
2364                    userId = Binder.getOrigCallingUser();
2365                }
2366            }
2367        }
2368        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2369                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2370                null, null, options, userId);
2371    }
2372
2373    public final WaitResult startActivityAndWait(IApplicationThread caller,
2374            Intent intent, String resolvedType, IBinder resultTo,
2375            String resultWho, int requestCode, int startFlags, String profileFile,
2376            ParcelFileDescriptor profileFd, Bundle options) {
2377        enforceNotIsolatedCaller("startActivityAndWait");
2378        WaitResult res = new WaitResult();
2379        int userId = Binder.getOrigCallingUser();
2380        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2381                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2382                res, null, options, userId);
2383        return res;
2384    }
2385
2386    public final int startActivityWithConfig(IApplicationThread caller,
2387            Intent intent, String resolvedType, IBinder resultTo,
2388            String resultWho, int requestCode, int startFlags, Configuration config,
2389            Bundle options) {
2390        enforceNotIsolatedCaller("startActivityWithConfig");
2391        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2392                resultTo, resultWho, requestCode, startFlags,
2393                null, null, null, config, options, Binder.getOrigCallingUser());
2394        return ret;
2395    }
2396
2397    public int startActivityIntentSender(IApplicationThread caller,
2398            IntentSender intent, Intent fillInIntent, String resolvedType,
2399            IBinder resultTo, String resultWho, int requestCode,
2400            int flagsMask, int flagsValues, Bundle options) {
2401        enforceNotIsolatedCaller("startActivityIntentSender");
2402        // Refuse possible leaked file descriptors
2403        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2404            throw new IllegalArgumentException("File descriptors passed in Intent");
2405        }
2406
2407        IIntentSender sender = intent.getTarget();
2408        if (!(sender instanceof PendingIntentRecord)) {
2409            throw new IllegalArgumentException("Bad PendingIntent object");
2410        }
2411
2412        PendingIntentRecord pir = (PendingIntentRecord)sender;
2413
2414        synchronized (this) {
2415            // If this is coming from the currently resumed activity, it is
2416            // effectively saying that app switches are allowed at this point.
2417            if (mMainStack.mResumedActivity != null
2418                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2419                            Binder.getCallingUid()) {
2420                mAppSwitchesAllowedTime = 0;
2421            }
2422        }
2423        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2424                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2425        return ret;
2426    }
2427
2428    public boolean startNextMatchingActivity(IBinder callingActivity,
2429            Intent intent, Bundle options) {
2430        // Refuse possible leaked file descriptors
2431        if (intent != null && intent.hasFileDescriptors() == true) {
2432            throw new IllegalArgumentException("File descriptors passed in Intent");
2433        }
2434
2435        synchronized (this) {
2436            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2437            if (r == null) {
2438                ActivityOptions.abort(options);
2439                return false;
2440            }
2441            if (r.app == null || r.app.thread == null) {
2442                // The caller is not running...  d'oh!
2443                ActivityOptions.abort(options);
2444                return false;
2445            }
2446            intent = new Intent(intent);
2447            // The caller is not allowed to change the data.
2448            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2449            // And we are resetting to find the next component...
2450            intent.setComponent(null);
2451
2452            ActivityInfo aInfo = null;
2453            try {
2454                List<ResolveInfo> resolves =
2455                    AppGlobals.getPackageManager().queryIntentActivities(
2456                            intent, r.resolvedType,
2457                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2458                            UserId.getCallingUserId());
2459
2460                // Look for the original activity in the list...
2461                final int N = resolves != null ? resolves.size() : 0;
2462                for (int i=0; i<N; i++) {
2463                    ResolveInfo rInfo = resolves.get(i);
2464                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2465                            && rInfo.activityInfo.name.equals(r.info.name)) {
2466                        // We found the current one...  the next matching is
2467                        // after it.
2468                        i++;
2469                        if (i<N) {
2470                            aInfo = resolves.get(i).activityInfo;
2471                        }
2472                        break;
2473                    }
2474                }
2475            } catch (RemoteException e) {
2476            }
2477
2478            if (aInfo == null) {
2479                // Nobody who is next!
2480                ActivityOptions.abort(options);
2481                return false;
2482            }
2483
2484            intent.setComponent(new ComponentName(
2485                    aInfo.applicationInfo.packageName, aInfo.name));
2486            intent.setFlags(intent.getFlags()&~(
2487                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2488                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2489                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2490                    Intent.FLAG_ACTIVITY_NEW_TASK));
2491
2492            // Okay now we need to start the new activity, replacing the
2493            // currently running activity.  This is a little tricky because
2494            // we want to start the new one as if the current one is finished,
2495            // but not finish the current one first so that there is no flicker.
2496            // And thus...
2497            final boolean wasFinishing = r.finishing;
2498            r.finishing = true;
2499
2500            // Propagate reply information over to the new activity.
2501            final ActivityRecord resultTo = r.resultTo;
2502            final String resultWho = r.resultWho;
2503            final int requestCode = r.requestCode;
2504            r.resultTo = null;
2505            if (resultTo != null) {
2506                resultTo.removeResultsLocked(r, resultWho, requestCode);
2507            }
2508
2509            final long origId = Binder.clearCallingIdentity();
2510            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2511                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2512                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2513                    options, false, null);
2514            Binder.restoreCallingIdentity(origId);
2515
2516            r.finishing = wasFinishing;
2517            if (res != ActivityManager.START_SUCCESS) {
2518                return false;
2519            }
2520            return true;
2521        }
2522    }
2523
2524    public final int startActivityInPackage(int uid,
2525            Intent intent, String resolvedType, IBinder resultTo,
2526            String resultWho, int requestCode, int startFlags, Bundle options) {
2527
2528        // This is so super not safe, that only the system (or okay root)
2529        // can do it.
2530        int userId = Binder.getOrigCallingUser();
2531        final int callingUid = Binder.getCallingUid();
2532        if (callingUid != 0 && callingUid != Process.myUid()) {
2533            throw new SecurityException(
2534                    "startActivityInPackage only available to the system");
2535        }
2536
2537        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2538                resultTo, resultWho, requestCode, startFlags,
2539                null, null, null, null, options, userId);
2540        return ret;
2541    }
2542
2543    public final int startActivities(IApplicationThread caller,
2544            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2545        enforceNotIsolatedCaller("startActivities");
2546        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2547                options, Binder.getOrigCallingUser());
2548        return ret;
2549    }
2550
2551    public final int startActivitiesInPackage(int uid,
2552            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2553            Bundle options) {
2554
2555        // This is so super not safe, that only the system (or okay root)
2556        // can do it.
2557        final int callingUid = Binder.getCallingUid();
2558        if (callingUid != 0 && callingUid != Process.myUid()) {
2559            throw new SecurityException(
2560                    "startActivityInPackage only available to the system");
2561        }
2562        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2563                options, UserId.getUserId(uid));
2564        return ret;
2565    }
2566
2567    final void addRecentTaskLocked(TaskRecord task) {
2568        int N = mRecentTasks.size();
2569        // Quick case: check if the top-most recent task is the same.
2570        if (N > 0 && mRecentTasks.get(0) == task) {
2571            return;
2572        }
2573        // Remove any existing entries that are the same kind of task.
2574        for (int i=0; i<N; i++) {
2575            TaskRecord tr = mRecentTasks.get(i);
2576            if (task.userId == tr.userId
2577                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2578                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2579                mRecentTasks.remove(i);
2580                i--;
2581                N--;
2582                if (task.intent == null) {
2583                    // If the new recent task we are adding is not fully
2584                    // specified, then replace it with the existing recent task.
2585                    task = tr;
2586                }
2587            }
2588        }
2589        if (N >= MAX_RECENT_TASKS) {
2590            mRecentTasks.remove(N-1);
2591        }
2592        mRecentTasks.add(0, task);
2593    }
2594
2595    public void setRequestedOrientation(IBinder token,
2596            int requestedOrientation) {
2597        synchronized (this) {
2598            ActivityRecord r = mMainStack.isInStackLocked(token);
2599            if (r == null) {
2600                return;
2601            }
2602            final long origId = Binder.clearCallingIdentity();
2603            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2604            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2605                    mConfiguration,
2606                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2607            if (config != null) {
2608                r.frozenBeforeDestroy = true;
2609                if (!updateConfigurationLocked(config, r, false, false)) {
2610                    mMainStack.resumeTopActivityLocked(null);
2611                }
2612            }
2613            Binder.restoreCallingIdentity(origId);
2614        }
2615    }
2616
2617    public int getRequestedOrientation(IBinder token) {
2618        synchronized (this) {
2619            ActivityRecord r = mMainStack.isInStackLocked(token);
2620            if (r == null) {
2621                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2622            }
2623            return mWindowManager.getAppOrientation(r.appToken);
2624        }
2625    }
2626
2627    /**
2628     * This is the internal entry point for handling Activity.finish().
2629     *
2630     * @param token The Binder token referencing the Activity we want to finish.
2631     * @param resultCode Result code, if any, from this Activity.
2632     * @param resultData Result data (Intent), if any, from this Activity.
2633     *
2634     * @return Returns true if the activity successfully finished, or false if it is still running.
2635     */
2636    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2637        // Refuse possible leaked file descriptors
2638        if (resultData != null && resultData.hasFileDescriptors() == true) {
2639            throw new IllegalArgumentException("File descriptors passed in Intent");
2640        }
2641
2642        synchronized(this) {
2643            if (mController != null) {
2644                // Find the first activity that is not finishing.
2645                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2646                if (next != null) {
2647                    // ask watcher if this is allowed
2648                    boolean resumeOK = true;
2649                    try {
2650                        resumeOK = mController.activityResuming(next.packageName);
2651                    } catch (RemoteException e) {
2652                        mController = null;
2653                    }
2654
2655                    if (!resumeOK) {
2656                        return false;
2657                    }
2658                }
2659            }
2660            final long origId = Binder.clearCallingIdentity();
2661            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2662                    resultData, "app-request");
2663            Binder.restoreCallingIdentity(origId);
2664            return res;
2665        }
2666    }
2667
2668    public final void finishHeavyWeightApp() {
2669        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2670                != PackageManager.PERMISSION_GRANTED) {
2671            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2672                    + Binder.getCallingPid()
2673                    + ", uid=" + Binder.getCallingUid()
2674                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2675            Slog.w(TAG, msg);
2676            throw new SecurityException(msg);
2677        }
2678
2679        synchronized(this) {
2680            if (mHeavyWeightProcess == null) {
2681                return;
2682            }
2683
2684            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2685                    mHeavyWeightProcess.activities);
2686            for (int i=0; i<activities.size(); i++) {
2687                ActivityRecord r = activities.get(i);
2688                if (!r.finishing) {
2689                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2690                    if (index >= 0) {
2691                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2692                                null, "finish-heavy");
2693                    }
2694                }
2695            }
2696
2697            mHeavyWeightProcess = null;
2698            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2699        }
2700    }
2701
2702    public void crashApplication(int uid, int initialPid, String packageName,
2703            String message) {
2704        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2705                != PackageManager.PERMISSION_GRANTED) {
2706            String msg = "Permission Denial: crashApplication() from pid="
2707                    + Binder.getCallingPid()
2708                    + ", uid=" + Binder.getCallingUid()
2709                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2710            Slog.w(TAG, msg);
2711            throw new SecurityException(msg);
2712        }
2713
2714        synchronized(this) {
2715            ProcessRecord proc = null;
2716
2717            // Figure out which process to kill.  We don't trust that initialPid
2718            // still has any relation to current pids, so must scan through the
2719            // list.
2720            synchronized (mPidsSelfLocked) {
2721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2722                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2723                    if (p.uid != uid) {
2724                        continue;
2725                    }
2726                    if (p.pid == initialPid) {
2727                        proc = p;
2728                        break;
2729                    }
2730                    for (String str : p.pkgList) {
2731                        if (str.equals(packageName)) {
2732                            proc = p;
2733                        }
2734                    }
2735                }
2736            }
2737
2738            if (proc == null) {
2739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2740                        + " initialPid=" + initialPid
2741                        + " packageName=" + packageName);
2742                return;
2743            }
2744
2745            if (proc.thread != null) {
2746                if (proc.pid == Process.myPid()) {
2747                    Log.w(TAG, "crashApplication: trying to crash self!");
2748                    return;
2749                }
2750                long ident = Binder.clearCallingIdentity();
2751                try {
2752                    proc.thread.scheduleCrash(message);
2753                } catch (RemoteException e) {
2754                }
2755                Binder.restoreCallingIdentity(ident);
2756            }
2757        }
2758    }
2759
2760    public final void finishSubActivity(IBinder token, String resultWho,
2761            int requestCode) {
2762        synchronized(this) {
2763            final long origId = Binder.clearCallingIdentity();
2764            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2765            Binder.restoreCallingIdentity(origId);
2766        }
2767    }
2768
2769    public boolean finishActivityAffinity(IBinder token) {
2770        synchronized(this) {
2771            final long origId = Binder.clearCallingIdentity();
2772            boolean res = mMainStack.finishActivityAffinityLocked(token);
2773            Binder.restoreCallingIdentity(origId);
2774            return res;
2775        }
2776    }
2777
2778    public boolean willActivityBeVisible(IBinder token) {
2779        synchronized(this) {
2780            int i;
2781            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2782                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2783                if (r.appToken == token) {
2784                    return true;
2785                }
2786                if (r.fullscreen && !r.finishing) {
2787                    return false;
2788                }
2789            }
2790            return true;
2791        }
2792    }
2793
2794    public void overridePendingTransition(IBinder token, String packageName,
2795            int enterAnim, int exitAnim) {
2796        synchronized(this) {
2797            ActivityRecord self = mMainStack.isInStackLocked(token);
2798            if (self == null) {
2799                return;
2800            }
2801
2802            final long origId = Binder.clearCallingIdentity();
2803
2804            if (self.state == ActivityState.RESUMED
2805                    || self.state == ActivityState.PAUSING) {
2806                mWindowManager.overridePendingAppTransition(packageName,
2807                        enterAnim, exitAnim, null);
2808            }
2809
2810            Binder.restoreCallingIdentity(origId);
2811        }
2812    }
2813
2814    /**
2815     * Main function for removing an existing process from the activity manager
2816     * as a result of that process going away.  Clears out all connections
2817     * to the process.
2818     */
2819    private final void handleAppDiedLocked(ProcessRecord app,
2820            boolean restarting, boolean allowRestart) {
2821        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2822        if (!restarting) {
2823            mLruProcesses.remove(app);
2824        }
2825
2826        if (mProfileProc == app) {
2827            clearProfilerLocked();
2828        }
2829
2830        // Just in case...
2831        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2832            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2833            mMainStack.mPausingActivity = null;
2834        }
2835        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2836            mMainStack.mLastPausedActivity = null;
2837        }
2838
2839        // Remove this application's activities from active lists.
2840        mMainStack.removeHistoryRecordsForAppLocked(app);
2841
2842        boolean atTop = true;
2843        boolean hasVisibleActivities = false;
2844
2845        // Clean out the history list.
2846        int i = mMainStack.mHistory.size();
2847        if (localLOGV) Slog.v(
2848            TAG, "Removing app " + app + " from history with " + i + " entries");
2849        while (i > 0) {
2850            i--;
2851            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2852            if (localLOGV) Slog.v(
2853                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2854            if (r.app == app) {
2855                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2856                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2857                        RuntimeException here = new RuntimeException("here");
2858                        here.fillInStackTrace();
2859                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2860                                + ": haveState=" + r.haveState
2861                                + " stateNotNeeded=" + r.stateNotNeeded
2862                                + " finishing=" + r.finishing
2863                                + " state=" + r.state, here);
2864                    }
2865                    if (!r.finishing) {
2866                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2867                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2868                                System.identityHashCode(r),
2869                                r.task.taskId, r.shortComponentName,
2870                                "proc died without state saved");
2871                    }
2872                    mMainStack.removeActivityFromHistoryLocked(r);
2873
2874                } else {
2875                    // We have the current state for this activity, so
2876                    // it can be restarted later when needed.
2877                    if (localLOGV) Slog.v(
2878                        TAG, "Keeping entry, setting app to null");
2879                    if (r.visible) {
2880                        hasVisibleActivities = true;
2881                    }
2882                    r.app = null;
2883                    r.nowVisible = false;
2884                    if (!r.haveState) {
2885                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2886                                "App died, clearing saved state of " + r);
2887                        r.icicle = null;
2888                    }
2889                }
2890
2891                r.stack.cleanUpActivityLocked(r, true, true);
2892            }
2893            atTop = false;
2894        }
2895
2896        app.activities.clear();
2897
2898        if (app.instrumentationClass != null) {
2899            Slog.w(TAG, "Crash of app " + app.processName
2900                  + " running instrumentation " + app.instrumentationClass);
2901            Bundle info = new Bundle();
2902            info.putString("shortMsg", "Process crashed.");
2903            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2904        }
2905
2906        if (!restarting) {
2907            if (!mMainStack.resumeTopActivityLocked(null)) {
2908                // If there was nothing to resume, and we are not already
2909                // restarting this process, but there is a visible activity that
2910                // is hosted by the process...  then make sure all visible
2911                // activities are running, taking care of restarting this
2912                // process.
2913                if (hasVisibleActivities) {
2914                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2915                }
2916            }
2917        }
2918    }
2919
2920    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2921        IBinder threadBinder = thread.asBinder();
2922        // Find the application record.
2923        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2924            ProcessRecord rec = mLruProcesses.get(i);
2925            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2926                return i;
2927            }
2928        }
2929        return -1;
2930    }
2931
2932    final ProcessRecord getRecordForAppLocked(
2933            IApplicationThread thread) {
2934        if (thread == null) {
2935            return null;
2936        }
2937
2938        int appIndex = getLRURecordIndexForAppLocked(thread);
2939        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2940    }
2941
2942    final void appDiedLocked(ProcessRecord app, int pid,
2943            IApplicationThread thread) {
2944
2945        mProcDeaths[0]++;
2946
2947        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2948        synchronized (stats) {
2949            stats.noteProcessDiedLocked(app.info.uid, pid);
2950        }
2951
2952        // Clean up already done if the process has been re-started.
2953        if (app.pid == pid && app.thread != null &&
2954                app.thread.asBinder() == thread.asBinder()) {
2955            if (!app.killedBackground) {
2956                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2957                        + ") has died.");
2958            }
2959            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2960            if (localLOGV) Slog.v(
2961                TAG, "Dying app: " + app + ", pid: " + pid
2962                + ", thread: " + thread.asBinder());
2963            boolean doLowMem = app.instrumentationClass == null;
2964            handleAppDiedLocked(app, false, true);
2965
2966            if (doLowMem) {
2967                // If there are no longer any background processes running,
2968                // and the app that died was not running instrumentation,
2969                // then tell everyone we are now low on memory.
2970                boolean haveBg = false;
2971                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2972                    ProcessRecord rec = mLruProcesses.get(i);
2973                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2974                        haveBg = true;
2975                        break;
2976                    }
2977                }
2978
2979                if (!haveBg) {
2980                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2981                    long now = SystemClock.uptimeMillis();
2982                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2983                        ProcessRecord rec = mLruProcesses.get(i);
2984                        if (rec != app && rec.thread != null &&
2985                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2986                            // The low memory report is overriding any current
2987                            // state for a GC request.  Make sure to do
2988                            // heavy/important/visible/foreground processes first.
2989                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2990                                rec.lastRequestedGc = 0;
2991                            } else {
2992                                rec.lastRequestedGc = rec.lastLowMemory;
2993                            }
2994                            rec.reportLowMemory = true;
2995                            rec.lastLowMemory = now;
2996                            mProcessesToGc.remove(rec);
2997                            addProcessToGcListLocked(rec);
2998                        }
2999                    }
3000                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3001                    scheduleAppGcsLocked();
3002                }
3003            }
3004        } else if (app.pid != pid) {
3005            // A new process has already been started.
3006            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3007                    + ") has died and restarted (pid " + app.pid + ").");
3008            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3009        } else if (DEBUG_PROCESSES) {
3010            Slog.d(TAG, "Received spurious death notification for thread "
3011                    + thread.asBinder());
3012        }
3013    }
3014
3015    /**
3016     * If a stack trace dump file is configured, dump process stack traces.
3017     * @param clearTraces causes the dump file to be erased prior to the new
3018     *    traces being written, if true; when false, the new traces will be
3019     *    appended to any existing file content.
3020     * @param firstPids of dalvik VM processes to dump stack traces for first
3021     * @param lastPids of dalvik VM processes to dump stack traces for last
3022     * @param nativeProcs optional list of native process names to dump stack crawls
3023     * @return file containing stack traces, or null if no dump file is configured
3024     */
3025    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3026            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3028        if (tracesPath == null || tracesPath.length() == 0) {
3029            return null;
3030        }
3031
3032        File tracesFile = new File(tracesPath);
3033        try {
3034            File tracesDir = tracesFile.getParentFile();
3035            if (!tracesDir.exists()) tracesFile.mkdirs();
3036            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3037
3038            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3039            tracesFile.createNewFile();
3040            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3041        } catch (IOException e) {
3042            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3043            return null;
3044        }
3045
3046        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3047        return tracesFile;
3048    }
3049
3050    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3051            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3052        // Use a FileObserver to detect when traces finish writing.
3053        // The order of traces is considered important to maintain for legibility.
3054        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3055            public synchronized void onEvent(int event, String path) { notify(); }
3056        };
3057
3058        try {
3059            observer.startWatching();
3060
3061            // First collect all of the stacks of the most important pids.
3062            if (firstPids != null) {
3063                try {
3064                    int num = firstPids.size();
3065                    for (int i = 0; i < num; i++) {
3066                        synchronized (observer) {
3067                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3068                            observer.wait(200);  // Wait for write-close, give up after 200msec
3069                        }
3070                    }
3071                } catch (InterruptedException e) {
3072                    Log.wtf(TAG, e);
3073                }
3074            }
3075
3076            // Next measure CPU usage.
3077            if (processStats != null) {
3078                processStats.init();
3079                System.gc();
3080                processStats.update();
3081                try {
3082                    synchronized (processStats) {
3083                        processStats.wait(500); // measure over 1/2 second.
3084                    }
3085                } catch (InterruptedException e) {
3086                }
3087                processStats.update();
3088
3089                // We'll take the stack crawls of just the top apps using CPU.
3090                final int N = processStats.countWorkingStats();
3091                int numProcs = 0;
3092                for (int i=0; i<N && numProcs<5; i++) {
3093                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3094                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3095                        numProcs++;
3096                        try {
3097                            synchronized (observer) {
3098                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3099                                observer.wait(200);  // Wait for write-close, give up after 200msec
3100                            }
3101                        } catch (InterruptedException e) {
3102                            Log.wtf(TAG, e);
3103                        }
3104
3105                    }
3106                }
3107            }
3108
3109        } finally {
3110            observer.stopWatching();
3111        }
3112
3113        if (nativeProcs != null) {
3114            int[] pids = Process.getPidsForCommands(nativeProcs);
3115            if (pids != null) {
3116                for (int pid : pids) {
3117                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3118                }
3119            }
3120        }
3121    }
3122
3123    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3124        if (true || IS_USER_BUILD) {
3125            return;
3126        }
3127        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3128        if (tracesPath == null || tracesPath.length() == 0) {
3129            return;
3130        }
3131
3132        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3133        StrictMode.allowThreadDiskWrites();
3134        try {
3135            final File tracesFile = new File(tracesPath);
3136            final File tracesDir = tracesFile.getParentFile();
3137            final File tracesTmp = new File(tracesDir, "__tmp__");
3138            try {
3139                if (!tracesDir.exists()) tracesFile.mkdirs();
3140                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3141
3142                if (tracesFile.exists()) {
3143                    tracesTmp.delete();
3144                    tracesFile.renameTo(tracesTmp);
3145                }
3146                StringBuilder sb = new StringBuilder();
3147                Time tobj = new Time();
3148                tobj.set(System.currentTimeMillis());
3149                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3150                sb.append(": ");
3151                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3152                sb.append(" since ");
3153                sb.append(msg);
3154                FileOutputStream fos = new FileOutputStream(tracesFile);
3155                fos.write(sb.toString().getBytes());
3156                if (app == null) {
3157                    fos.write("\n*** No application process!".getBytes());
3158                }
3159                fos.close();
3160                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3161            } catch (IOException e) {
3162                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3163                return;
3164            }
3165
3166            if (app != null) {
3167                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3168                firstPids.add(app.pid);
3169                dumpStackTraces(tracesPath, firstPids, null, null, null);
3170            }
3171
3172            File lastTracesFile = null;
3173            File curTracesFile = null;
3174            for (int i=9; i>=0; i--) {
3175                String name = String.format("slow%02d.txt", i);
3176                curTracesFile = new File(tracesDir, name);
3177                if (curTracesFile.exists()) {
3178                    if (lastTracesFile != null) {
3179                        curTracesFile.renameTo(lastTracesFile);
3180                    } else {
3181                        curTracesFile.delete();
3182                    }
3183                }
3184                lastTracesFile = curTracesFile;
3185            }
3186            tracesFile.renameTo(curTracesFile);
3187            if (tracesTmp.exists()) {
3188                tracesTmp.renameTo(tracesFile);
3189            }
3190        } finally {
3191            StrictMode.setThreadPolicy(oldPolicy);
3192        }
3193    }
3194
3195    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3196            ActivityRecord parent, final String annotation) {
3197        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3198        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3199
3200        if (mController != null) {
3201            try {
3202                // 0 == continue, -1 = kill process immediately
3203                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3204                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3205            } catch (RemoteException e) {
3206                mController = null;
3207            }
3208        }
3209
3210        long anrTime = SystemClock.uptimeMillis();
3211        if (MONITOR_CPU_USAGE) {
3212            updateCpuStatsNow();
3213        }
3214
3215        synchronized (this) {
3216            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3217            if (mShuttingDown) {
3218                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3219                return;
3220            } else if (app.notResponding) {
3221                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3222                return;
3223            } else if (app.crashing) {
3224                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3225                return;
3226            }
3227
3228            // In case we come through here for the same app before completing
3229            // this one, mark as anring now so we will bail out.
3230            app.notResponding = true;
3231
3232            // Log the ANR to the event log.
3233            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3234                    annotation);
3235
3236            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3237            firstPids.add(app.pid);
3238
3239            int parentPid = app.pid;
3240            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3241            if (parentPid != app.pid) firstPids.add(parentPid);
3242
3243            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3244
3245            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3246                ProcessRecord r = mLruProcesses.get(i);
3247                if (r != null && r.thread != null) {
3248                    int pid = r.pid;
3249                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3250                        if (r.persistent) {
3251                            firstPids.add(pid);
3252                        } else {
3253                            lastPids.put(pid, Boolean.TRUE);
3254                        }
3255                    }
3256                }
3257            }
3258        }
3259
3260        // Log the ANR to the main log.
3261        StringBuilder info = new StringBuilder();
3262        info.setLength(0);
3263        info.append("ANR in ").append(app.processName);
3264        if (activity != null && activity.shortComponentName != null) {
3265            info.append(" (").append(activity.shortComponentName).append(")");
3266        }
3267        info.append("\n");
3268        if (annotation != null) {
3269            info.append("Reason: ").append(annotation).append("\n");
3270        }
3271        if (parent != null && parent != activity) {
3272            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3273        }
3274
3275        final ProcessStats processStats = new ProcessStats(true);
3276
3277        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3278
3279        String cpuInfo = null;
3280        if (MONITOR_CPU_USAGE) {
3281            updateCpuStatsNow();
3282            synchronized (mProcessStatsThread) {
3283                cpuInfo = mProcessStats.printCurrentState(anrTime);
3284            }
3285            info.append(processStats.printCurrentLoad());
3286            info.append(cpuInfo);
3287        }
3288
3289        info.append(processStats.printCurrentState(anrTime));
3290
3291        Slog.e(TAG, info.toString());
3292        if (tracesFile == null) {
3293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3295        }
3296
3297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3298                cpuInfo, tracesFile, null);
3299
3300        if (mController != null) {
3301            try {
3302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3304                if (res != 0) {
3305                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3306                    return;
3307                }
3308            } catch (RemoteException e) {
3309                mController = null;
3310            }
3311        }
3312
3313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3316
3317        synchronized (this) {
3318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3319                Slog.w(TAG, "Killing " + app + ": background ANR");
3320                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3321                        app.processName, app.setAdj, "background ANR");
3322                Process.killProcessQuiet(app.pid);
3323                return;
3324            }
3325
3326            // Set the app's notResponding state, and look up the errorReportReceiver
3327            makeAppNotRespondingLocked(app,
3328                    activity != null ? activity.shortComponentName : null,
3329                    annotation != null ? "ANR " + annotation : "ANR",
3330                    info.toString());
3331
3332            // Bring up the infamous App Not Responding dialog
3333            Message msg = Message.obtain();
3334            HashMap map = new HashMap();
3335            msg.what = SHOW_NOT_RESPONDING_MSG;
3336            msg.obj = map;
3337            map.put("app", app);
3338            if (activity != null) {
3339                map.put("activity", activity);
3340            }
3341
3342            mHandler.sendMessage(msg);
3343        }
3344    }
3345
3346    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3347        if (!mLaunchWarningShown) {
3348            mLaunchWarningShown = true;
3349            mHandler.post(new Runnable() {
3350                @Override
3351                public void run() {
3352                    synchronized (ActivityManagerService.this) {
3353                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3354                        d.show();
3355                        mHandler.postDelayed(new Runnable() {
3356                            @Override
3357                            public void run() {
3358                                synchronized (ActivityManagerService.this) {
3359                                    d.dismiss();
3360                                    mLaunchWarningShown = false;
3361                                }
3362                            }
3363                        }, 4000);
3364                    }
3365                }
3366            });
3367        }
3368    }
3369
3370    public boolean clearApplicationUserData(final String packageName,
3371            final IPackageDataObserver observer, final int userId) {
3372        enforceNotIsolatedCaller("clearApplicationUserData");
3373        int uid = Binder.getCallingUid();
3374        int pid = Binder.getCallingPid();
3375        long callingId = Binder.clearCallingIdentity();
3376        try {
3377            IPackageManager pm = AppGlobals.getPackageManager();
3378            int pkgUid = -1;
3379            synchronized(this) {
3380                try {
3381                    pkgUid = pm.getPackageUid(packageName, userId);
3382                } catch (RemoteException e) {
3383                }
3384                if (pkgUid == -1) {
3385                    Slog.w(TAG, "Invalid packageName:" + packageName);
3386                    return false;
3387                }
3388                if (uid == pkgUid || checkComponentPermission(
3389                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3390                        pid, uid, -1, true)
3391                        == PackageManager.PERMISSION_GRANTED) {
3392                    forceStopPackageLocked(packageName, pkgUid);
3393                } else {
3394                    throw new SecurityException(pid+" does not have permission:"+
3395                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3396                                    "for process:"+packageName);
3397                }
3398            }
3399
3400            try {
3401                //clear application user data
3402                pm.clearApplicationUserData(packageName, observer, userId);
3403                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3404                        Uri.fromParts("package", packageName, null));
3405                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3406                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3407                        null, null, 0, null, null, null, false, false, userId);
3408            } catch (RemoteException e) {
3409            }
3410        } finally {
3411            Binder.restoreCallingIdentity(callingId);
3412        }
3413        return true;
3414    }
3415
3416    public void killBackgroundProcesses(final String packageName) {
3417        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3418                != PackageManager.PERMISSION_GRANTED &&
3419                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3420                        != PackageManager.PERMISSION_GRANTED) {
3421            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3422                    + Binder.getCallingPid()
3423                    + ", uid=" + Binder.getCallingUid()
3424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3425            Slog.w(TAG, msg);
3426            throw new SecurityException(msg);
3427        }
3428
3429        int userId = UserId.getCallingUserId();
3430        long callingId = Binder.clearCallingIdentity();
3431        try {
3432            IPackageManager pm = AppGlobals.getPackageManager();
3433            int pkgUid = -1;
3434            synchronized(this) {
3435                try {
3436                    pkgUid = pm.getPackageUid(packageName, userId);
3437                } catch (RemoteException e) {
3438                }
3439                if (pkgUid == -1) {
3440                    Slog.w(TAG, "Invalid packageName: " + packageName);
3441                    return;
3442                }
3443                killPackageProcessesLocked(packageName, pkgUid,
3444                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3445            }
3446        } finally {
3447            Binder.restoreCallingIdentity(callingId);
3448        }
3449    }
3450
3451    public void killAllBackgroundProcesses() {
3452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        long callingId = Binder.clearCallingIdentity();
3463        try {
3464            synchronized(this) {
3465                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3466                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3467                    final int NA = apps.size();
3468                    for (int ia=0; ia<NA; ia++) {
3469                        ProcessRecord app = apps.valueAt(ia);
3470                        if (app.persistent) {
3471                            // we don't kill persistent processes
3472                            continue;
3473                        }
3474                        if (app.removed) {
3475                            procs.add(app);
3476                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3477                            app.removed = true;
3478                            procs.add(app);
3479                        }
3480                    }
3481                }
3482
3483                int N = procs.size();
3484                for (int i=0; i<N; i++) {
3485                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3486                }
3487            }
3488        } finally {
3489            Binder.restoreCallingIdentity(callingId);
3490        }
3491    }
3492
3493    public void forceStopPackage(final String packageName) {
3494        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3495                != PackageManager.PERMISSION_GRANTED) {
3496            String msg = "Permission Denial: forceStopPackage() from pid="
3497                    + Binder.getCallingPid()
3498                    + ", uid=" + Binder.getCallingUid()
3499                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3500            Slog.w(TAG, msg);
3501            throw new SecurityException(msg);
3502        }
3503        final int userId = UserId.getCallingUserId();
3504        long callingId = Binder.clearCallingIdentity();
3505        try {
3506            IPackageManager pm = AppGlobals.getPackageManager();
3507            int pkgUid = -1;
3508            synchronized(this) {
3509                try {
3510                    pkgUid = pm.getPackageUid(packageName, userId);
3511                } catch (RemoteException e) {
3512                }
3513                if (pkgUid == -1) {
3514                    Slog.w(TAG, "Invalid packageName: " + packageName);
3515                    return;
3516                }
3517                forceStopPackageLocked(packageName, pkgUid);
3518                try {
3519                    pm.setPackageStoppedState(packageName, true, userId);
3520                } catch (RemoteException e) {
3521                } catch (IllegalArgumentException e) {
3522                    Slog.w(TAG, "Failed trying to unstop package "
3523                            + packageName + ": " + e);
3524                }
3525            }
3526        } finally {
3527            Binder.restoreCallingIdentity(callingId);
3528        }
3529    }
3530
3531    /*
3532     * The pkg name and uid have to be specified.
3533     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3534     */
3535    public void killApplicationWithUid(String pkg, int uid) {
3536        if (pkg == null) {
3537            return;
3538        }
3539        // Make sure the uid is valid.
3540        if (uid < 0) {
3541            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3542            return;
3543        }
3544        int callerUid = Binder.getCallingUid();
3545        // Only the system server can kill an application
3546        if (callerUid == Process.SYSTEM_UID) {
3547            // Post an aysnc message to kill the application
3548            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3549            msg.arg1 = uid;
3550            msg.arg2 = 0;
3551            msg.obj = pkg;
3552            mHandler.sendMessage(msg);
3553        } else {
3554            throw new SecurityException(callerUid + " cannot kill pkg: " +
3555                    pkg);
3556        }
3557    }
3558
3559    public void closeSystemDialogs(String reason) {
3560        enforceNotIsolatedCaller("closeSystemDialogs");
3561
3562        final int uid = Binder.getCallingUid();
3563        final long origId = Binder.clearCallingIdentity();
3564        synchronized (this) {
3565            closeSystemDialogsLocked(uid, reason);
3566        }
3567        Binder.restoreCallingIdentity(origId);
3568    }
3569
3570    void closeSystemDialogsLocked(int callingUid, String reason) {
3571        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3572        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3573        if (reason != null) {
3574            intent.putExtra("reason", reason);
3575        }
3576        mWindowManager.closeSystemDialogs(reason);
3577
3578        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3579            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3580            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3581                r.stack.finishActivityLocked(r, i,
3582                        Activity.RESULT_CANCELED, null, "close-sys");
3583            }
3584        }
3585
3586        broadcastIntentLocked(null, null, intent, null,
3587                null, 0, null, null, null, false, false, -1,
3588                callingUid, 0 /* TODO: Verify */);
3589    }
3590
3591    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3592            throws RemoteException {
3593        enforceNotIsolatedCaller("getProcessMemoryInfo");
3594        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3595        for (int i=pids.length-1; i>=0; i--) {
3596            infos[i] = new Debug.MemoryInfo();
3597            Debug.getMemoryInfo(pids[i], infos[i]);
3598        }
3599        return infos;
3600    }
3601
3602    public long[] getProcessPss(int[] pids) throws RemoteException {
3603        enforceNotIsolatedCaller("getProcessPss");
3604        long[] pss = new long[pids.length];
3605        for (int i=pids.length-1; i>=0; i--) {
3606            pss[i] = Debug.getPss(pids[i]);
3607        }
3608        return pss;
3609    }
3610
3611    public void killApplicationProcess(String processName, int uid) {
3612        if (processName == null) {
3613            return;
3614        }
3615
3616        int callerUid = Binder.getCallingUid();
3617        // Only the system server can kill an application
3618        if (callerUid == Process.SYSTEM_UID) {
3619            synchronized (this) {
3620                ProcessRecord app = getProcessRecordLocked(processName, uid);
3621                if (app != null && app.thread != null) {
3622                    try {
3623                        app.thread.scheduleSuicide();
3624                    } catch (RemoteException e) {
3625                        // If the other end already died, then our work here is done.
3626                    }
3627                } else {
3628                    Slog.w(TAG, "Process/uid not found attempting kill of "
3629                            + processName + " / " + uid);
3630                }
3631            }
3632        } else {
3633            throw new SecurityException(callerUid + " cannot kill app process: " +
3634                    processName);
3635        }
3636    }
3637
3638    private void forceStopPackageLocked(final String packageName, int uid) {
3639        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3640        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3641                Uri.fromParts("package", packageName, null));
3642        if (!mProcessesReady) {
3643            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3644        }
3645        intent.putExtra(Intent.EXTRA_UID, uid);
3646        broadcastIntentLocked(null, null, intent,
3647                null, null, 0, null, null, null,
3648                false, false,
3649                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3650    }
3651
3652    private final boolean killPackageProcessesLocked(String packageName, int uid,
3653            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3654            boolean evenPersistent, String reason) {
3655        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3656
3657        // Remove all processes this package may have touched: all with the
3658        // same UID (except for the system or root user), and all whose name
3659        // matches the package name.
3660        final String procNamePrefix = packageName + ":";
3661        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3662            final int NA = apps.size();
3663            for (int ia=0; ia<NA; ia++) {
3664                ProcessRecord app = apps.valueAt(ia);
3665                if (app.persistent && !evenPersistent) {
3666                    // we don't kill persistent processes
3667                    continue;
3668                }
3669                if (app.removed) {
3670                    if (doit) {
3671                        procs.add(app);
3672                    }
3673                // If uid is specified and the uid and process name match
3674                // Or, the uid is not specified and the process name matches
3675                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3676                            || ((app.processName.equals(packageName)
3677                                 || app.processName.startsWith(procNamePrefix))
3678                                && uid < 0))) {
3679                    if (app.setAdj >= minOomAdj) {
3680                        if (!doit) {
3681                            return true;
3682                        }
3683                        app.removed = true;
3684                        procs.add(app);
3685                    }
3686                }
3687            }
3688        }
3689
3690        int N = procs.size();
3691        for (int i=0; i<N; i++) {
3692            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3693        }
3694        return N > 0;
3695    }
3696
3697    private final boolean forceStopPackageLocked(String name, int uid,
3698            boolean callerWillRestart, boolean purgeCache, boolean doit,
3699            boolean evenPersistent, int userId) {
3700        int i;
3701        int N;
3702
3703        if (uid < 0) {
3704            try {
3705                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3706            } catch (RemoteException e) {
3707            }
3708        }
3709
3710        if (doit) {
3711            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3712
3713            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3714            while (badApps.hasNext()) {
3715                SparseArray<Long> ba = badApps.next();
3716                if (ba.get(uid) != null) {
3717                    badApps.remove();
3718                }
3719            }
3720        }
3721
3722        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3723                callerWillRestart, false, doit, evenPersistent, "force stop");
3724
3725        TaskRecord lastTask = null;
3726        for (i=0; i<mMainStack.mHistory.size(); i++) {
3727            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3728            final boolean samePackage = r.packageName.equals(name);
3729            if (r.userId == userId
3730                    && (samePackage || r.task == lastTask)
3731                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3732                if (!doit) {
3733                    if (r.finishing) {
3734                        // If this activity is just finishing, then it is not
3735                        // interesting as far as something to stop.
3736                        continue;
3737                    }
3738                    return true;
3739                }
3740                didSomething = true;
3741                Slog.i(TAG, "  Force finishing activity " + r);
3742                if (samePackage) {
3743                    if (r.app != null) {
3744                        r.app.removed = true;
3745                    }
3746                    r.app = null;
3747                }
3748                lastTask = r.task;
3749                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3750                        null, "force-stop", true)) {
3751                    i--;
3752                }
3753            }
3754        }
3755
3756        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3757            if (!doit) {
3758                return true;
3759            }
3760            didSomething = true;
3761        }
3762
3763        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3764        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3765            if (provider.info.packageName.equals(name)
3766                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3767                if (!doit) {
3768                    return true;
3769                }
3770                didSomething = true;
3771                providers.add(provider);
3772            }
3773        }
3774
3775        N = providers.size();
3776        for (i=0; i<N; i++) {
3777            removeDyingProviderLocked(null, providers.get(i), true);
3778        }
3779
3780        if (doit) {
3781            if (purgeCache) {
3782                AttributeCache ac = AttributeCache.instance();
3783                if (ac != null) {
3784                    ac.removePackage(name);
3785                }
3786            }
3787            if (mBooted) {
3788                mMainStack.resumeTopActivityLocked(null);
3789                mMainStack.scheduleIdleLocked();
3790            }
3791        }
3792
3793        return didSomething;
3794    }
3795
3796    private final boolean removeProcessLocked(ProcessRecord app,
3797            boolean callerWillRestart, boolean allowRestart, String reason) {
3798        final String name = app.processName;
3799        final int uid = app.uid;
3800        if (DEBUG_PROCESSES) Slog.d(
3801            TAG, "Force removing proc " + app.toShortString() + " (" + name
3802            + "/" + uid + ")");
3803
3804        mProcessNames.remove(name, uid);
3805        mIsolatedProcesses.remove(app.uid);
3806        if (mHeavyWeightProcess == app) {
3807            mHeavyWeightProcess = null;
3808            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3809        }
3810        boolean needRestart = false;
3811        if (app.pid > 0 && app.pid != MY_PID) {
3812            int pid = app.pid;
3813            synchronized (mPidsSelfLocked) {
3814                mPidsSelfLocked.remove(pid);
3815                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3816            }
3817            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3818            handleAppDiedLocked(app, true, allowRestart);
3819            mLruProcesses.remove(app);
3820            Process.killProcessQuiet(pid);
3821
3822            if (app.persistent && !app.isolated) {
3823                if (!callerWillRestart) {
3824                    addAppLocked(app.info, false);
3825                } else {
3826                    needRestart = true;
3827                }
3828            }
3829        } else {
3830            mRemovedProcesses.add(app);
3831        }
3832
3833        return needRestart;
3834    }
3835
3836    private final void processStartTimedOutLocked(ProcessRecord app) {
3837        final int pid = app.pid;
3838        boolean gone = false;
3839        synchronized (mPidsSelfLocked) {
3840            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3841            if (knownApp != null && knownApp.thread == null) {
3842                mPidsSelfLocked.remove(pid);
3843                gone = true;
3844            }
3845        }
3846
3847        if (gone) {
3848            Slog.w(TAG, "Process " + app + " failed to attach");
3849            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3850                    app.processName);
3851            mProcessNames.remove(app.processName, app.uid);
3852            mIsolatedProcesses.remove(app.uid);
3853            if (mHeavyWeightProcess == app) {
3854                mHeavyWeightProcess = null;
3855                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3856            }
3857            // Take care of any launching providers waiting for this process.
3858            checkAppInLaunchingProvidersLocked(app, true);
3859            // Take care of any services that are waiting for the process.
3860            mServices.processStartTimedOutLocked(app);
3861            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3862                    app.processName, app.setAdj, "start timeout");
3863            Process.killProcessQuiet(pid);
3864            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3865                Slog.w(TAG, "Unattached app died before backup, skipping");
3866                try {
3867                    IBackupManager bm = IBackupManager.Stub.asInterface(
3868                            ServiceManager.getService(Context.BACKUP_SERVICE));
3869                    bm.agentDisconnected(app.info.packageName);
3870                } catch (RemoteException e) {
3871                    // Can't happen; the backup manager is local
3872                }
3873            }
3874            if (isPendingBroadcastProcessLocked(pid)) {
3875                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3876                skipPendingBroadcastLocked(pid);
3877            }
3878        } else {
3879            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3880        }
3881    }
3882
3883    private final boolean attachApplicationLocked(IApplicationThread thread,
3884            int pid) {
3885
3886        // Find the application record that is being attached...  either via
3887        // the pid if we are running in multiple processes, or just pull the
3888        // next app record if we are emulating process with anonymous threads.
3889        ProcessRecord app;
3890        if (pid != MY_PID && pid >= 0) {
3891            synchronized (mPidsSelfLocked) {
3892                app = mPidsSelfLocked.get(pid);
3893            }
3894        } else {
3895            app = null;
3896        }
3897
3898        if (app == null) {
3899            Slog.w(TAG, "No pending application record for pid " + pid
3900                    + " (IApplicationThread " + thread + "); dropping process");
3901            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3902            if (pid > 0 && pid != MY_PID) {
3903                Process.killProcessQuiet(pid);
3904            } else {
3905                try {
3906                    thread.scheduleExit();
3907                } catch (Exception e) {
3908                    // Ignore exceptions.
3909                }
3910            }
3911            return false;
3912        }
3913
3914        // If this application record is still attached to a previous
3915        // process, clean it up now.
3916        if (app.thread != null) {
3917            handleAppDiedLocked(app, true, true);
3918        }
3919
3920        // Tell the process all about itself.
3921
3922        if (localLOGV) Slog.v(
3923                TAG, "Binding process pid " + pid + " to record " + app);
3924
3925        String processName = app.processName;
3926        try {
3927            AppDeathRecipient adr = new AppDeathRecipient(
3928                    app, pid, thread);
3929            thread.asBinder().linkToDeath(adr, 0);
3930            app.deathRecipient = adr;
3931        } catch (RemoteException e) {
3932            app.resetPackageList();
3933            startProcessLocked(app, "link fail", processName);
3934            return false;
3935        }
3936
3937        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3938
3939        app.thread = thread;
3940        app.curAdj = app.setAdj = -100;
3941        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3942        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3943        app.forcingToForeground = null;
3944        app.foregroundServices = false;
3945        app.hasShownUi = false;
3946        app.debugging = false;
3947
3948        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3949
3950        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3951        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3952
3953        if (!normalMode) {
3954            Slog.i(TAG, "Launching preboot mode app: " + app);
3955        }
3956
3957        if (localLOGV) Slog.v(
3958            TAG, "New app record " + app
3959            + " thread=" + thread.asBinder() + " pid=" + pid);
3960        try {
3961            int testMode = IApplicationThread.DEBUG_OFF;
3962            if (mDebugApp != null && mDebugApp.equals(processName)) {
3963                testMode = mWaitForDebugger
3964                    ? IApplicationThread.DEBUG_WAIT
3965                    : IApplicationThread.DEBUG_ON;
3966                app.debugging = true;
3967                if (mDebugTransient) {
3968                    mDebugApp = mOrigDebugApp;
3969                    mWaitForDebugger = mOrigWaitForDebugger;
3970                }
3971            }
3972            String profileFile = app.instrumentationProfileFile;
3973            ParcelFileDescriptor profileFd = null;
3974            boolean profileAutoStop = false;
3975            if (mProfileApp != null && mProfileApp.equals(processName)) {
3976                mProfileProc = app;
3977                profileFile = mProfileFile;
3978                profileFd = mProfileFd;
3979                profileAutoStop = mAutoStopProfiler;
3980            }
3981            boolean enableOpenGlTrace = false;
3982            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3983                enableOpenGlTrace = true;
3984                mOpenGlTraceApp = null;
3985            }
3986
3987            // If the app is being launched for restore or full backup, set it up specially
3988            boolean isRestrictedBackupMode = false;
3989            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3990                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3991                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3992                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3993            }
3994
3995            ensurePackageDexOpt(app.instrumentationInfo != null
3996                    ? app.instrumentationInfo.packageName
3997                    : app.info.packageName);
3998            if (app.instrumentationClass != null) {
3999                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4000            }
4001            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4002                    + processName + " with config " + mConfiguration);
4003            ApplicationInfo appInfo = app.instrumentationInfo != null
4004                    ? app.instrumentationInfo : app.info;
4005            app.compat = compatibilityInfoForPackageLocked(appInfo);
4006            if (profileFd != null) {
4007                profileFd = profileFd.dup();
4008            }
4009            thread.bindApplication(processName, appInfo, providers,
4010                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4011                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4012                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4013                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4014                    mCoreSettingsObserver.getCoreSettingsLocked());
4015            updateLruProcessLocked(app, false, true);
4016            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4017        } catch (Exception e) {
4018            // todo: Yikes!  What should we do?  For now we will try to
4019            // start another process, but that could easily get us in
4020            // an infinite loop of restarting processes...
4021            Slog.w(TAG, "Exception thrown during bind!", e);
4022
4023            app.resetPackageList();
4024            app.unlinkDeathRecipient();
4025            startProcessLocked(app, "bind fail", processName);
4026            return false;
4027        }
4028
4029        // Remove this record from the list of starting applications.
4030        mPersistentStartingProcesses.remove(app);
4031        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4032                "Attach application locked removing on hold: " + app);
4033        mProcessesOnHold.remove(app);
4034
4035        boolean badApp = false;
4036        boolean didSomething = false;
4037
4038        // See if the top visible activity is waiting to run in this process...
4039        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4040        if (hr != null && normalMode) {
4041            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4042                    && processName.equals(hr.processName)) {
4043                try {
4044                    if (mHeadless) {
4045                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4046                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4047                        didSomething = true;
4048                    }
4049                } catch (Exception e) {
4050                    Slog.w(TAG, "Exception in new application when starting activity "
4051                          + hr.intent.getComponent().flattenToShortString(), e);
4052                    badApp = true;
4053                }
4054            } else {
4055                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4056            }
4057        }
4058
4059        // Find any services that should be running in this process...
4060        if (!badApp) {
4061            try {
4062                didSomething |= mServices.attachApplicationLocked(app, processName);
4063            } catch (Exception e) {
4064                badApp = true;
4065            }
4066        }
4067
4068        // Check if a next-broadcast receiver is in this process...
4069        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4070            try {
4071                didSomething = sendPendingBroadcastsLocked(app);
4072            } catch (Exception e) {
4073                // If the app died trying to launch the receiver we declare it 'bad'
4074                badApp = true;
4075            }
4076        }
4077
4078        // Check whether the next backup agent is in this process...
4079        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4080            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4081            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4082            try {
4083                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4084                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4085                        mBackupTarget.backupMode);
4086            } catch (Exception e) {
4087                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4088                e.printStackTrace();
4089            }
4090        }
4091
4092        if (badApp) {
4093            // todo: Also need to kill application to deal with all
4094            // kinds of exceptions.
4095            handleAppDiedLocked(app, false, true);
4096            return false;
4097        }
4098
4099        if (!didSomething) {
4100            updateOomAdjLocked();
4101        }
4102
4103        return true;
4104    }
4105
4106    public final void attachApplication(IApplicationThread thread) {
4107        synchronized (this) {
4108            int callingPid = Binder.getCallingPid();
4109            final long origId = Binder.clearCallingIdentity();
4110            attachApplicationLocked(thread, callingPid);
4111            Binder.restoreCallingIdentity(origId);
4112        }
4113    }
4114
4115    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4116        final long origId = Binder.clearCallingIdentity();
4117        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4118        if (stopProfiling) {
4119            synchronized (this) {
4120                if (mProfileProc == r.app) {
4121                    if (mProfileFd != null) {
4122                        try {
4123                            mProfileFd.close();
4124                        } catch (IOException e) {
4125                        }
4126                        clearProfilerLocked();
4127                    }
4128                }
4129            }
4130        }
4131        Binder.restoreCallingIdentity(origId);
4132    }
4133
4134    void enableScreenAfterBoot() {
4135        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4136                SystemClock.uptimeMillis());
4137        mWindowManager.enableScreenAfterBoot();
4138
4139        synchronized (this) {
4140            updateEventDispatchingLocked();
4141        }
4142    }
4143
4144    public void showBootMessage(final CharSequence msg, final boolean always) {
4145        enforceNotIsolatedCaller("showBootMessage");
4146        mWindowManager.showBootMessage(msg, always);
4147    }
4148
4149    public void dismissKeyguardOnNextActivity() {
4150        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4151        final long token = Binder.clearCallingIdentity();
4152        try {
4153            synchronized (this) {
4154                if (mLockScreenShown) {
4155                    mLockScreenShown = false;
4156                    comeOutOfSleepIfNeededLocked();
4157                }
4158                mMainStack.dismissKeyguardOnNextActivityLocked();
4159            }
4160        } finally {
4161            Binder.restoreCallingIdentity(token);
4162        }
4163    }
4164
4165    final void finishBooting() {
4166        IntentFilter pkgFilter = new IntentFilter();
4167        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4168        pkgFilter.addDataScheme("package");
4169        mContext.registerReceiver(new BroadcastReceiver() {
4170            @Override
4171            public void onReceive(Context context, Intent intent) {
4172                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4173                if (pkgs != null) {
4174                    for (String pkg : pkgs) {
4175                        synchronized (ActivityManagerService.this) {
4176                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4177                                setResultCode(Activity.RESULT_OK);
4178                                return;
4179                            }
4180                        }
4181                    }
4182                }
4183            }
4184        }, pkgFilter);
4185
4186        IntentFilter userFilter = new IntentFilter();
4187        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4188        mContext.registerReceiver(new BroadcastReceiver() {
4189            @Override
4190            public void onReceive(Context context, Intent intent) {
4191                onUserRemoved(intent);
4192            }
4193        }, userFilter);
4194
4195        synchronized (this) {
4196            // Ensure that any processes we had put on hold are now started
4197            // up.
4198            final int NP = mProcessesOnHold.size();
4199            if (NP > 0) {
4200                ArrayList<ProcessRecord> procs =
4201                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4202                for (int ip=0; ip<NP; ip++) {
4203                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4204                            + procs.get(ip));
4205                    startProcessLocked(procs.get(ip), "on-hold", null);
4206                }
4207            }
4208
4209            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4210                // Start looking for apps that are abusing wake locks.
4211                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4212                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4213                // Tell anyone interested that we are done booting!
4214                SystemProperties.set("sys.boot_completed", "1");
4215                SystemProperties.set("dev.bootcomplete", "1");
4216                List<UserInfo> users = getUserManager().getUsers();
4217                for (UserInfo user : users) {
4218                    broadcastIntentLocked(null, null,
4219                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4220                            null, null, 0, null, null,
4221                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4222                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4223                }
4224            }
4225        }
4226    }
4227
4228    final void ensureBootCompleted() {
4229        boolean booting;
4230        boolean enableScreen;
4231        synchronized (this) {
4232            booting = mBooting;
4233            mBooting = false;
4234            enableScreen = !mBooted;
4235            mBooted = true;
4236        }
4237
4238        if (booting) {
4239            finishBooting();
4240        }
4241
4242        if (enableScreen) {
4243            enableScreenAfterBoot();
4244        }
4245    }
4246
4247    public final void activityPaused(IBinder token) {
4248        final long origId = Binder.clearCallingIdentity();
4249        mMainStack.activityPaused(token, false);
4250        Binder.restoreCallingIdentity(origId);
4251    }
4252
4253    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4254            CharSequence description) {
4255        if (localLOGV) Slog.v(
4256            TAG, "Activity stopped: token=" + token);
4257
4258        // Refuse possible leaked file descriptors
4259        if (icicle != null && icicle.hasFileDescriptors()) {
4260            throw new IllegalArgumentException("File descriptors passed in Bundle");
4261        }
4262
4263        ActivityRecord r = null;
4264
4265        final long origId = Binder.clearCallingIdentity();
4266
4267        synchronized (this) {
4268            r = mMainStack.isInStackLocked(token);
4269            if (r != null) {
4270                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4271            }
4272        }
4273
4274        if (r != null) {
4275            sendPendingThumbnail(r, null, null, null, false);
4276        }
4277
4278        trimApplications();
4279
4280        Binder.restoreCallingIdentity(origId);
4281    }
4282
4283    public final void activityDestroyed(IBinder token) {
4284        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4285        mMainStack.activityDestroyed(token);
4286    }
4287
4288    public String getCallingPackage(IBinder token) {
4289        synchronized (this) {
4290            ActivityRecord r = getCallingRecordLocked(token);
4291            return r != null && r.app != null ? r.info.packageName : null;
4292        }
4293    }
4294
4295    public ComponentName getCallingActivity(IBinder token) {
4296        synchronized (this) {
4297            ActivityRecord r = getCallingRecordLocked(token);
4298            return r != null ? r.intent.getComponent() : null;
4299        }
4300    }
4301
4302    private ActivityRecord getCallingRecordLocked(IBinder token) {
4303        ActivityRecord r = mMainStack.isInStackLocked(token);
4304        if (r == null) {
4305            return null;
4306        }
4307        return r.resultTo;
4308    }
4309
4310    public ComponentName getActivityClassForToken(IBinder token) {
4311        synchronized(this) {
4312            ActivityRecord r = mMainStack.isInStackLocked(token);
4313            if (r == null) {
4314                return null;
4315            }
4316            return r.intent.getComponent();
4317        }
4318    }
4319
4320    public String getPackageForToken(IBinder token) {
4321        synchronized(this) {
4322            ActivityRecord r = mMainStack.isInStackLocked(token);
4323            if (r == null) {
4324                return null;
4325            }
4326            return r.packageName;
4327        }
4328    }
4329
4330    public IIntentSender getIntentSender(int type,
4331            String packageName, IBinder token, String resultWho,
4332            int requestCode, Intent[] intents, String[] resolvedTypes,
4333            int flags, Bundle options) {
4334        enforceNotIsolatedCaller("getIntentSender");
4335        // Refuse possible leaked file descriptors
4336        if (intents != null) {
4337            if (intents.length < 1) {
4338                throw new IllegalArgumentException("Intents array length must be >= 1");
4339            }
4340            for (int i=0; i<intents.length; i++) {
4341                Intent intent = intents[i];
4342                if (intent != null) {
4343                    if (intent.hasFileDescriptors()) {
4344                        throw new IllegalArgumentException("File descriptors passed in Intent");
4345                    }
4346                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4347                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4348                        throw new IllegalArgumentException(
4349                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4350                    }
4351                    intents[i] = new Intent(intent);
4352                }
4353            }
4354            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4355                throw new IllegalArgumentException(
4356                        "Intent array length does not match resolvedTypes length");
4357            }
4358        }
4359        if (options != null) {
4360            if (options.hasFileDescriptors()) {
4361                throw new IllegalArgumentException("File descriptors passed in options");
4362            }
4363        }
4364
4365        synchronized(this) {
4366            int callingUid = Binder.getCallingUid();
4367            try {
4368                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4369                    int uid = AppGlobals.getPackageManager()
4370                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4371                    if (!UserId.isSameApp(callingUid, uid)) {
4372                        String msg = "Permission Denial: getIntentSender() from pid="
4373                            + Binder.getCallingPid()
4374                            + ", uid=" + Binder.getCallingUid()
4375                            + ", (need uid=" + uid + ")"
4376                            + " is not allowed to send as package " + packageName;
4377                        Slog.w(TAG, msg);
4378                        throw new SecurityException(msg);
4379                    }
4380                }
4381
4382                if (DEBUG_MU)
4383                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4384                            + Binder.getOrigCallingUid());
4385                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4386                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4387
4388            } catch (RemoteException e) {
4389                throw new SecurityException(e);
4390            }
4391        }
4392    }
4393
4394    IIntentSender getIntentSenderLocked(int type,
4395            String packageName, int callingUid, IBinder token, String resultWho,
4396            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4397            Bundle options) {
4398        if (DEBUG_MU)
4399            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4400        ActivityRecord activity = null;
4401        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4402            activity = mMainStack.isInStackLocked(token);
4403            if (activity == null) {
4404                return null;
4405            }
4406            if (activity.finishing) {
4407                return null;
4408            }
4409        }
4410
4411        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4412        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4413        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4414        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4415                |PendingIntent.FLAG_UPDATE_CURRENT);
4416
4417        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4418                type, packageName, activity, resultWho,
4419                requestCode, intents, resolvedTypes, flags, options);
4420        WeakReference<PendingIntentRecord> ref;
4421        ref = mIntentSenderRecords.get(key);
4422        PendingIntentRecord rec = ref != null ? ref.get() : null;
4423        if (rec != null) {
4424            if (!cancelCurrent) {
4425                if (updateCurrent) {
4426                    if (rec.key.requestIntent != null) {
4427                        rec.key.requestIntent.replaceExtras(intents != null ?
4428                                intents[intents.length - 1] : null);
4429                    }
4430                    if (intents != null) {
4431                        intents[intents.length-1] = rec.key.requestIntent;
4432                        rec.key.allIntents = intents;
4433                        rec.key.allResolvedTypes = resolvedTypes;
4434                    } else {
4435                        rec.key.allIntents = null;
4436                        rec.key.allResolvedTypes = null;
4437                    }
4438                }
4439                return rec;
4440            }
4441            rec.canceled = true;
4442            mIntentSenderRecords.remove(key);
4443        }
4444        if (noCreate) {
4445            return rec;
4446        }
4447        rec = new PendingIntentRecord(this, key, callingUid);
4448        mIntentSenderRecords.put(key, rec.ref);
4449        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4450            if (activity.pendingResults == null) {
4451                activity.pendingResults
4452                        = new HashSet<WeakReference<PendingIntentRecord>>();
4453            }
4454            activity.pendingResults.add(rec.ref);
4455        }
4456        return rec;
4457    }
4458
4459    public void cancelIntentSender(IIntentSender sender) {
4460        if (!(sender instanceof PendingIntentRecord)) {
4461            return;
4462        }
4463        synchronized(this) {
4464            PendingIntentRecord rec = (PendingIntentRecord)sender;
4465            try {
4466                int uid = AppGlobals.getPackageManager()
4467                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4468                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4469                    String msg = "Permission Denial: cancelIntentSender() from pid="
4470                        + Binder.getCallingPid()
4471                        + ", uid=" + Binder.getCallingUid()
4472                        + " is not allowed to cancel packges "
4473                        + rec.key.packageName;
4474                    Slog.w(TAG, msg);
4475                    throw new SecurityException(msg);
4476                }
4477            } catch (RemoteException e) {
4478                throw new SecurityException(e);
4479            }
4480            cancelIntentSenderLocked(rec, true);
4481        }
4482    }
4483
4484    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4485        rec.canceled = true;
4486        mIntentSenderRecords.remove(rec.key);
4487        if (cleanActivity && rec.key.activity != null) {
4488            rec.key.activity.pendingResults.remove(rec.ref);
4489        }
4490    }
4491
4492    public String getPackageForIntentSender(IIntentSender pendingResult) {
4493        if (!(pendingResult instanceof PendingIntentRecord)) {
4494            return null;
4495        }
4496        try {
4497            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4498            return res.key.packageName;
4499        } catch (ClassCastException e) {
4500        }
4501        return null;
4502    }
4503
4504    public int getUidForIntentSender(IIntentSender sender) {
4505        if (sender instanceof PendingIntentRecord) {
4506            try {
4507                PendingIntentRecord res = (PendingIntentRecord)sender;
4508                return res.uid;
4509            } catch (ClassCastException e) {
4510            }
4511        }
4512        return -1;
4513    }
4514
4515    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4516        if (!(pendingResult instanceof PendingIntentRecord)) {
4517            return false;
4518        }
4519        try {
4520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4521            if (res.key.allIntents == null) {
4522                return false;
4523            }
4524            for (int i=0; i<res.key.allIntents.length; i++) {
4525                Intent intent = res.key.allIntents[i];
4526                if (intent.getPackage() != null && intent.getComponent() != null) {
4527                    return false;
4528                }
4529            }
4530            return true;
4531        } catch (ClassCastException e) {
4532        }
4533        return false;
4534    }
4535
4536    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4537        if (!(pendingResult instanceof PendingIntentRecord)) {
4538            return false;
4539        }
4540        try {
4541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4542            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4543                return true;
4544            }
4545            return false;
4546        } catch (ClassCastException e) {
4547        }
4548        return false;
4549    }
4550
4551    public void setProcessLimit(int max) {
4552        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4553                "setProcessLimit()");
4554        synchronized (this) {
4555            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4556            mProcessLimitOverride = max;
4557        }
4558        trimApplications();
4559    }
4560
4561    public int getProcessLimit() {
4562        synchronized (this) {
4563            return mProcessLimitOverride;
4564        }
4565    }
4566
4567    void foregroundTokenDied(ForegroundToken token) {
4568        synchronized (ActivityManagerService.this) {
4569            synchronized (mPidsSelfLocked) {
4570                ForegroundToken cur
4571                    = mForegroundProcesses.get(token.pid);
4572                if (cur != token) {
4573                    return;
4574                }
4575                mForegroundProcesses.remove(token.pid);
4576                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4577                if (pr == null) {
4578                    return;
4579                }
4580                pr.forcingToForeground = null;
4581                pr.foregroundServices = false;
4582            }
4583            updateOomAdjLocked();
4584        }
4585    }
4586
4587    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4588        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4589                "setProcessForeground()");
4590        synchronized(this) {
4591            boolean changed = false;
4592
4593            synchronized (mPidsSelfLocked) {
4594                ProcessRecord pr = mPidsSelfLocked.get(pid);
4595                if (pr == null && isForeground) {
4596                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4597                    return;
4598                }
4599                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4600                if (oldToken != null) {
4601                    oldToken.token.unlinkToDeath(oldToken, 0);
4602                    mForegroundProcesses.remove(pid);
4603                    if (pr != null) {
4604                        pr.forcingToForeground = null;
4605                    }
4606                    changed = true;
4607                }
4608                if (isForeground && token != null) {
4609                    ForegroundToken newToken = new ForegroundToken() {
4610                        public void binderDied() {
4611                            foregroundTokenDied(this);
4612                        }
4613                    };
4614                    newToken.pid = pid;
4615                    newToken.token = token;
4616                    try {
4617                        token.linkToDeath(newToken, 0);
4618                        mForegroundProcesses.put(pid, newToken);
4619                        pr.forcingToForeground = token;
4620                        changed = true;
4621                    } catch (RemoteException e) {
4622                        // If the process died while doing this, we will later
4623                        // do the cleanup with the process death link.
4624                    }
4625                }
4626            }
4627
4628            if (changed) {
4629                updateOomAdjLocked();
4630            }
4631        }
4632    }
4633
4634    // =========================================================
4635    // PERMISSIONS
4636    // =========================================================
4637
4638    static class PermissionController extends IPermissionController.Stub {
4639        ActivityManagerService mActivityManagerService;
4640        PermissionController(ActivityManagerService activityManagerService) {
4641            mActivityManagerService = activityManagerService;
4642        }
4643
4644        public boolean checkPermission(String permission, int pid, int uid) {
4645            return mActivityManagerService.checkPermission(permission, pid,
4646                    uid) == PackageManager.PERMISSION_GRANTED;
4647        }
4648    }
4649
4650    /**
4651     * This can be called with or without the global lock held.
4652     */
4653    int checkComponentPermission(String permission, int pid, int uid,
4654            int owningUid, boolean exported) {
4655        // We might be performing an operation on behalf of an indirect binder
4656        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4657        // client identity accordingly before proceeding.
4658        Identity tlsIdentity = sCallerIdentity.get();
4659        if (tlsIdentity != null) {
4660            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4661                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4662            uid = tlsIdentity.uid;
4663            pid = tlsIdentity.pid;
4664        }
4665
4666        if (pid == MY_PID) {
4667            return PackageManager.PERMISSION_GRANTED;
4668        }
4669
4670        return ActivityManager.checkComponentPermission(permission, uid,
4671                owningUid, exported);
4672    }
4673
4674    /**
4675     * As the only public entry point for permissions checking, this method
4676     * can enforce the semantic that requesting a check on a null global
4677     * permission is automatically denied.  (Internally a null permission
4678     * string is used when calling {@link #checkComponentPermission} in cases
4679     * when only uid-based security is needed.)
4680     *
4681     * This can be called with or without the global lock held.
4682     */
4683    public int checkPermission(String permission, int pid, int uid) {
4684        if (permission == null) {
4685            return PackageManager.PERMISSION_DENIED;
4686        }
4687        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4688    }
4689
4690    /**
4691     * Binder IPC calls go through the public entry point.
4692     * This can be called with or without the global lock held.
4693     */
4694    int checkCallingPermission(String permission) {
4695        return checkPermission(permission,
4696                Binder.getCallingPid(),
4697                UserId.getAppId(Binder.getCallingUid()));
4698    }
4699
4700    /**
4701     * This can be called with or without the global lock held.
4702     */
4703    void enforceCallingPermission(String permission, String func) {
4704        if (checkCallingPermission(permission)
4705                == PackageManager.PERMISSION_GRANTED) {
4706            return;
4707        }
4708
4709        String msg = "Permission Denial: " + func + " from pid="
4710                + Binder.getCallingPid()
4711                + ", uid=" + Binder.getCallingUid()
4712                + " requires " + permission;
4713        Slog.w(TAG, msg);
4714        throw new SecurityException(msg);
4715    }
4716
4717    /**
4718     * Determine if UID is holding permissions required to access {@link Uri} in
4719     * the given {@link ProviderInfo}. Final permission checking is always done
4720     * in {@link ContentProvider}.
4721     */
4722    private final boolean checkHoldingPermissionsLocked(
4723            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4724        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4725                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4726
4727        if (pi.applicationInfo.uid == uid) {
4728            return true;
4729        } else if (!pi.exported) {
4730            return false;
4731        }
4732
4733        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4734        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4735        try {
4736            // check if target holds top-level <provider> permissions
4737            if (!readMet && pi.readPermission != null
4738                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4739                readMet = true;
4740            }
4741            if (!writeMet && pi.writePermission != null
4742                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4743                writeMet = true;
4744            }
4745
4746            // track if unprotected read/write is allowed; any denied
4747            // <path-permission> below removes this ability
4748            boolean allowDefaultRead = pi.readPermission == null;
4749            boolean allowDefaultWrite = pi.writePermission == null;
4750
4751            // check if target holds any <path-permission> that match uri
4752            final PathPermission[] pps = pi.pathPermissions;
4753            if (pps != null) {
4754                final String path = uri.getPath();
4755                int i = pps.length;
4756                while (i > 0 && (!readMet || !writeMet)) {
4757                    i--;
4758                    PathPermission pp = pps[i];
4759                    if (pp.match(path)) {
4760                        if (!readMet) {
4761                            final String pprperm = pp.getReadPermission();
4762                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4763                                    + pprperm + " for " + pp.getPath()
4764                                    + ": match=" + pp.match(path)
4765                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4766                            if (pprperm != null) {
4767                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4768                                    readMet = true;
4769                                } else {
4770                                    allowDefaultRead = false;
4771                                }
4772                            }
4773                        }
4774                        if (!writeMet) {
4775                            final String ppwperm = pp.getWritePermission();
4776                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4777                                    + ppwperm + " for " + pp.getPath()
4778                                    + ": match=" + pp.match(path)
4779                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4780                            if (ppwperm != null) {
4781                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4782                                    writeMet = true;
4783                                } else {
4784                                    allowDefaultWrite = false;
4785                                }
4786                            }
4787                        }
4788                    }
4789                }
4790            }
4791
4792            // grant unprotected <provider> read/write, if not blocked by
4793            // <path-permission> above
4794            if (allowDefaultRead) readMet = true;
4795            if (allowDefaultWrite) writeMet = true;
4796
4797        } catch (RemoteException e) {
4798            return false;
4799        }
4800
4801        return readMet && writeMet;
4802    }
4803
4804    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4805            int modeFlags) {
4806        // Root gets to do everything.
4807        if (uid == 0) {
4808            return true;
4809        }
4810        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4811        if (perms == null) return false;
4812        UriPermission perm = perms.get(uri);
4813        if (perm == null) return false;
4814        return (modeFlags&perm.modeFlags) == modeFlags;
4815    }
4816
4817    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4818        enforceNotIsolatedCaller("checkUriPermission");
4819
4820        // Another redirected-binder-call permissions check as in
4821        // {@link checkComponentPermission}.
4822        Identity tlsIdentity = sCallerIdentity.get();
4823        if (tlsIdentity != null) {
4824            uid = tlsIdentity.uid;
4825            pid = tlsIdentity.pid;
4826        }
4827
4828        uid = UserId.getAppId(uid);
4829        // Our own process gets to do everything.
4830        if (pid == MY_PID) {
4831            return PackageManager.PERMISSION_GRANTED;
4832        }
4833        synchronized(this) {
4834            return checkUriPermissionLocked(uri, uid, modeFlags)
4835                    ? PackageManager.PERMISSION_GRANTED
4836                    : PackageManager.PERMISSION_DENIED;
4837        }
4838    }
4839
4840    /**
4841     * Check if the targetPkg can be granted permission to access uri by
4842     * the callingUid using the given modeFlags.  Throws a security exception
4843     * if callingUid is not allowed to do this.  Returns the uid of the target
4844     * if the URI permission grant should be performed; returns -1 if it is not
4845     * needed (for example targetPkg already has permission to access the URI).
4846     * If you already know the uid of the target, you can supply it in
4847     * lastTargetUid else set that to -1.
4848     */
4849    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4850            Uri uri, int modeFlags, int lastTargetUid) {
4851        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4852                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4853        if (modeFlags == 0) {
4854            return -1;
4855        }
4856
4857        if (targetPkg != null) {
4858            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4859                    "Checking grant " + targetPkg + " permission to " + uri);
4860        }
4861
4862        final IPackageManager pm = AppGlobals.getPackageManager();
4863
4864        // If this is not a content: uri, we can't do anything with it.
4865        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4866            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4867                    "Can't grant URI permission for non-content URI: " + uri);
4868            return -1;
4869        }
4870
4871        String name = uri.getAuthority();
4872        ProviderInfo pi = null;
4873        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4874                UserId.getUserId(callingUid));
4875        if (cpr != null) {
4876            pi = cpr.info;
4877        } else {
4878            try {
4879                pi = pm.resolveContentProvider(name,
4880                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4881            } catch (RemoteException ex) {
4882            }
4883        }
4884        if (pi == null) {
4885            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4886            return -1;
4887        }
4888
4889        int targetUid = lastTargetUid;
4890        if (targetUid < 0 && targetPkg != null) {
4891            try {
4892                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4893                if (targetUid < 0) {
4894                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4895                            "Can't grant URI permission no uid for: " + targetPkg);
4896                    return -1;
4897                }
4898            } catch (RemoteException ex) {
4899                return -1;
4900            }
4901        }
4902
4903        if (targetUid >= 0) {
4904            // First...  does the target actually need this permission?
4905            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4906                // No need to grant the target this permission.
4907                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4908                        "Target " + targetPkg + " already has full permission to " + uri);
4909                return -1;
4910            }
4911        } else {
4912            // First...  there is no target package, so can anyone access it?
4913            boolean allowed = pi.exported;
4914            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4915                if (pi.readPermission != null) {
4916                    allowed = false;
4917                }
4918            }
4919            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4920                if (pi.writePermission != null) {
4921                    allowed = false;
4922                }
4923            }
4924            if (allowed) {
4925                return -1;
4926            }
4927        }
4928
4929        // Second...  is the provider allowing granting of URI permissions?
4930        if (!pi.grantUriPermissions) {
4931            throw new SecurityException("Provider " + pi.packageName
4932                    + "/" + pi.name
4933                    + " does not allow granting of Uri permissions (uri "
4934                    + uri + ")");
4935        }
4936        if (pi.uriPermissionPatterns != null) {
4937            final int N = pi.uriPermissionPatterns.length;
4938            boolean allowed = false;
4939            for (int i=0; i<N; i++) {
4940                if (pi.uriPermissionPatterns[i] != null
4941                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4942                    allowed = true;
4943                    break;
4944                }
4945            }
4946            if (!allowed) {
4947                throw new SecurityException("Provider " + pi.packageName
4948                        + "/" + pi.name
4949                        + " does not allow granting of permission to path of Uri "
4950                        + uri);
4951            }
4952        }
4953
4954        // Third...  does the caller itself have permission to access
4955        // this uri?
4956        if (callingUid != Process.myUid()) {
4957            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4958                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4959                    throw new SecurityException("Uid " + callingUid
4960                            + " does not have permission to uri " + uri);
4961                }
4962            }
4963        }
4964
4965        return targetUid;
4966    }
4967
4968    public int checkGrantUriPermission(int callingUid, String targetPkg,
4969            Uri uri, int modeFlags) {
4970        enforceNotIsolatedCaller("checkGrantUriPermission");
4971        synchronized(this) {
4972            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4973        }
4974    }
4975
4976    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4977            Uri uri, int modeFlags, UriPermissionOwner owner) {
4978        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4979                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4980        if (modeFlags == 0) {
4981            return;
4982        }
4983
4984        // So here we are: the caller has the assumed permission
4985        // to the uri, and the target doesn't.  Let's now give this to
4986        // the target.
4987
4988        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4989                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4990
4991        HashMap<Uri, UriPermission> targetUris
4992                = mGrantedUriPermissions.get(targetUid);
4993        if (targetUris == null) {
4994            targetUris = new HashMap<Uri, UriPermission>();
4995            mGrantedUriPermissions.put(targetUid, targetUris);
4996        }
4997
4998        UriPermission perm = targetUris.get(uri);
4999        if (perm == null) {
5000            perm = new UriPermission(targetUid, uri);
5001            targetUris.put(uri, perm);
5002        }
5003
5004        perm.modeFlags |= modeFlags;
5005        if (owner == null) {
5006            perm.globalModeFlags |= modeFlags;
5007        } else {
5008            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5009                 perm.readOwners.add(owner);
5010                 owner.addReadPermission(perm);
5011            }
5012            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5013                 perm.writeOwners.add(owner);
5014                 owner.addWritePermission(perm);
5015            }
5016        }
5017    }
5018
5019    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5020            int modeFlags, UriPermissionOwner owner) {
5021        if (targetPkg == null) {
5022            throw new NullPointerException("targetPkg");
5023        }
5024
5025        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5026        if (targetUid < 0) {
5027            return;
5028        }
5029
5030        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5031    }
5032
5033    static class NeededUriGrants extends ArrayList<Uri> {
5034        final String targetPkg;
5035        final int targetUid;
5036        final int flags;
5037
5038        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5039            targetPkg = _targetPkg;
5040            targetUid = _targetUid;
5041            flags = _flags;
5042        }
5043    }
5044
5045    /**
5046     * Like checkGrantUriPermissionLocked, but takes an Intent.
5047     */
5048    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5049            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5050        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5051                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5052                + " clip=" + (intent != null ? intent.getClipData() : null)
5053                + " from " + intent + "; flags=0x"
5054                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5055
5056        if (targetPkg == null) {
5057            throw new NullPointerException("targetPkg");
5058        }
5059
5060        if (intent == null) {
5061            return null;
5062        }
5063        Uri data = intent.getData();
5064        ClipData clip = intent.getClipData();
5065        if (data == null && clip == null) {
5066            return null;
5067        }
5068        if (data != null) {
5069            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5070                mode, needed != null ? needed.targetUid : -1);
5071            if (target > 0) {
5072                if (needed == null) {
5073                    needed = new NeededUriGrants(targetPkg, target, mode);
5074                }
5075                needed.add(data);
5076            }
5077        }
5078        if (clip != null) {
5079            for (int i=0; i<clip.getItemCount(); i++) {
5080                Uri uri = clip.getItemAt(i).getUri();
5081                if (uri != null) {
5082                    int target = -1;
5083                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5084                            mode, needed != null ? needed.targetUid : -1);
5085                    if (target > 0) {
5086                        if (needed == null) {
5087                            needed = new NeededUriGrants(targetPkg, target, mode);
5088                        }
5089                        needed.add(uri);
5090                    }
5091                } else {
5092                    Intent clipIntent = clip.getItemAt(i).getIntent();
5093                    if (clipIntent != null) {
5094                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5095                                callingUid, targetPkg, clipIntent, mode, needed);
5096                        if (newNeeded != null) {
5097                            needed = newNeeded;
5098                        }
5099                    }
5100                }
5101            }
5102        }
5103
5104        return needed;
5105    }
5106
5107    /**
5108     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5109     */
5110    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5111            UriPermissionOwner owner) {
5112        if (needed != null) {
5113            for (int i=0; i<needed.size(); i++) {
5114                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5115                        needed.get(i), needed.flags, owner);
5116            }
5117        }
5118    }
5119
5120    void grantUriPermissionFromIntentLocked(int callingUid,
5121            String targetPkg, Intent intent, UriPermissionOwner owner) {
5122        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5123                intent, intent != null ? intent.getFlags() : 0, null);
5124        if (needed == null) {
5125            return;
5126        }
5127
5128        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5129    }
5130
5131    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5132            Uri uri, int modeFlags) {
5133        enforceNotIsolatedCaller("grantUriPermission");
5134        synchronized(this) {
5135            final ProcessRecord r = getRecordForAppLocked(caller);
5136            if (r == null) {
5137                throw new SecurityException("Unable to find app for caller "
5138                        + caller
5139                        + " when granting permission to uri " + uri);
5140            }
5141            if (targetPkg == null) {
5142                throw new IllegalArgumentException("null target");
5143            }
5144            if (uri == null) {
5145                throw new IllegalArgumentException("null uri");
5146            }
5147
5148            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5149                    null);
5150        }
5151    }
5152
5153    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5154        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5155                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5156            HashMap<Uri, UriPermission> perms
5157                    = mGrantedUriPermissions.get(perm.uid);
5158            if (perms != null) {
5159                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5160                        "Removing " + perm.uid + " permission to " + perm.uri);
5161                perms.remove(perm.uri);
5162                if (perms.size() == 0) {
5163                    mGrantedUriPermissions.remove(perm.uid);
5164                }
5165            }
5166        }
5167    }
5168
5169    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5170            int modeFlags) {
5171        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5172                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5173        if (modeFlags == 0) {
5174            return;
5175        }
5176
5177        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5178                "Revoking all granted permissions to " + uri);
5179
5180        final IPackageManager pm = AppGlobals.getPackageManager();
5181
5182        final String authority = uri.getAuthority();
5183        ProviderInfo pi = null;
5184        int userId = UserId.getUserId(callingUid);
5185        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5186        if (cpr != null) {
5187            pi = cpr.info;
5188        } else {
5189            try {
5190                pi = pm.resolveContentProvider(authority,
5191                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5192            } catch (RemoteException ex) {
5193            }
5194        }
5195        if (pi == null) {
5196            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5197            return;
5198        }
5199
5200        // Does the caller have this permission on the URI?
5201        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5202            // Right now, if you are not the original owner of the permission,
5203            // you are not allowed to revoke it.
5204            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5205                throw new SecurityException("Uid " + callingUid
5206                        + " does not have permission to uri " + uri);
5207            //}
5208        }
5209
5210        // Go through all of the permissions and remove any that match.
5211        final List<String> SEGMENTS = uri.getPathSegments();
5212        if (SEGMENTS != null) {
5213            final int NS = SEGMENTS.size();
5214            int N = mGrantedUriPermissions.size();
5215            for (int i=0; i<N; i++) {
5216                HashMap<Uri, UriPermission> perms
5217                        = mGrantedUriPermissions.valueAt(i);
5218                Iterator<UriPermission> it = perms.values().iterator();
5219            toploop:
5220                while (it.hasNext()) {
5221                    UriPermission perm = it.next();
5222                    Uri targetUri = perm.uri;
5223                    if (!authority.equals(targetUri.getAuthority())) {
5224                        continue;
5225                    }
5226                    List<String> targetSegments = targetUri.getPathSegments();
5227                    if (targetSegments == null) {
5228                        continue;
5229                    }
5230                    if (targetSegments.size() < NS) {
5231                        continue;
5232                    }
5233                    for (int j=0; j<NS; j++) {
5234                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5235                            continue toploop;
5236                        }
5237                    }
5238                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5239                            "Revoking " + perm.uid + " permission to " + perm.uri);
5240                    perm.clearModes(modeFlags);
5241                    if (perm.modeFlags == 0) {
5242                        it.remove();
5243                    }
5244                }
5245                if (perms.size() == 0) {
5246                    mGrantedUriPermissions.remove(
5247                            mGrantedUriPermissions.keyAt(i));
5248                    N--;
5249                    i--;
5250                }
5251            }
5252        }
5253    }
5254
5255    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5256            int modeFlags) {
5257        enforceNotIsolatedCaller("revokeUriPermission");
5258        synchronized(this) {
5259            final ProcessRecord r = getRecordForAppLocked(caller);
5260            if (r == null) {
5261                throw new SecurityException("Unable to find app for caller "
5262                        + caller
5263                        + " when revoking permission to uri " + uri);
5264            }
5265            if (uri == null) {
5266                Slog.w(TAG, "revokeUriPermission: null uri");
5267                return;
5268            }
5269
5270            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5271                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5272            if (modeFlags == 0) {
5273                return;
5274            }
5275
5276            final IPackageManager pm = AppGlobals.getPackageManager();
5277
5278            final String authority = uri.getAuthority();
5279            ProviderInfo pi = null;
5280            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5281            if (cpr != null) {
5282                pi = cpr.info;
5283            } else {
5284                try {
5285                    pi = pm.resolveContentProvider(authority,
5286                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5287                } catch (RemoteException ex) {
5288                }
5289            }
5290            if (pi == null) {
5291                Slog.w(TAG, "No content provider found for permission revoke: "
5292                        + uri.toSafeString());
5293                return;
5294            }
5295
5296            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5297        }
5298    }
5299
5300    @Override
5301    public IBinder newUriPermissionOwner(String name) {
5302        enforceNotIsolatedCaller("newUriPermissionOwner");
5303        synchronized(this) {
5304            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5305            return owner.getExternalTokenLocked();
5306        }
5307    }
5308
5309    @Override
5310    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5311            Uri uri, int modeFlags) {
5312        synchronized(this) {
5313            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5314            if (owner == null) {
5315                throw new IllegalArgumentException("Unknown owner: " + token);
5316            }
5317            if (fromUid != Binder.getCallingUid()) {
5318                if (Binder.getCallingUid() != Process.myUid()) {
5319                    // Only system code can grant URI permissions on behalf
5320                    // of other users.
5321                    throw new SecurityException("nice try");
5322                }
5323            }
5324            if (targetPkg == null) {
5325                throw new IllegalArgumentException("null target");
5326            }
5327            if (uri == null) {
5328                throw new IllegalArgumentException("null uri");
5329            }
5330
5331            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5332        }
5333    }
5334
5335    @Override
5336    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5337        synchronized(this) {
5338            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5339            if (owner == null) {
5340                throw new IllegalArgumentException("Unknown owner: " + token);
5341            }
5342
5343            if (uri == null) {
5344                owner.removeUriPermissionsLocked(mode);
5345            } else {
5346                owner.removeUriPermissionLocked(uri, mode);
5347            }
5348        }
5349    }
5350
5351    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5352        synchronized (this) {
5353            ProcessRecord app =
5354                who != null ? getRecordForAppLocked(who) : null;
5355            if (app == null) return;
5356
5357            Message msg = Message.obtain();
5358            msg.what = WAIT_FOR_DEBUGGER_MSG;
5359            msg.obj = app;
5360            msg.arg1 = waiting ? 1 : 0;
5361            mHandler.sendMessage(msg);
5362        }
5363    }
5364
5365    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5366        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5367        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5368        outInfo.availMem = Process.getFreeMemory();
5369        outInfo.totalMem = Process.getTotalMemory();
5370        outInfo.threshold = homeAppMem;
5371        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5372        outInfo.hiddenAppThreshold = hiddenAppMem;
5373        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5374                ProcessList.SERVICE_ADJ);
5375        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5376                ProcessList.VISIBLE_APP_ADJ);
5377        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5378                ProcessList.FOREGROUND_APP_ADJ);
5379    }
5380
5381    // =========================================================
5382    // TASK MANAGEMENT
5383    // =========================================================
5384
5385    public List getTasks(int maxNum, int flags,
5386                         IThumbnailReceiver receiver) {
5387        ArrayList list = new ArrayList();
5388
5389        PendingThumbnailsRecord pending = null;
5390        IApplicationThread topThumbnail = null;
5391        ActivityRecord topRecord = null;
5392
5393        synchronized(this) {
5394            if (localLOGV) Slog.v(
5395                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5396                + ", receiver=" + receiver);
5397
5398            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5399                    != PackageManager.PERMISSION_GRANTED) {
5400                if (receiver != null) {
5401                    // If the caller wants to wait for pending thumbnails,
5402                    // it ain't gonna get them.
5403                    try {
5404                        receiver.finished();
5405                    } catch (RemoteException ex) {
5406                    }
5407                }
5408                String msg = "Permission Denial: getTasks() from pid="
5409                        + Binder.getCallingPid()
5410                        + ", uid=" + Binder.getCallingUid()
5411                        + " requires " + android.Manifest.permission.GET_TASKS;
5412                Slog.w(TAG, msg);
5413                throw new SecurityException(msg);
5414            }
5415
5416            int pos = mMainStack.mHistory.size()-1;
5417            ActivityRecord next =
5418                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5419            ActivityRecord top = null;
5420            TaskRecord curTask = null;
5421            int numActivities = 0;
5422            int numRunning = 0;
5423            while (pos >= 0 && maxNum > 0) {
5424                final ActivityRecord r = next;
5425                pos--;
5426                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5427
5428                // Initialize state for next task if needed.
5429                if (top == null ||
5430                        (top.state == ActivityState.INITIALIZING
5431                            && top.task == r.task)) {
5432                    top = r;
5433                    curTask = r.task;
5434                    numActivities = numRunning = 0;
5435                }
5436
5437                // Add 'r' into the current task.
5438                numActivities++;
5439                if (r.app != null && r.app.thread != null) {
5440                    numRunning++;
5441                }
5442
5443                if (localLOGV) Slog.v(
5444                    TAG, r.intent.getComponent().flattenToShortString()
5445                    + ": task=" + r.task);
5446
5447                // If the next one is a different task, generate a new
5448                // TaskInfo entry for what we have.
5449                if (next == null || next.task != curTask) {
5450                    ActivityManager.RunningTaskInfo ci
5451                            = new ActivityManager.RunningTaskInfo();
5452                    ci.id = curTask.taskId;
5453                    ci.baseActivity = r.intent.getComponent();
5454                    ci.topActivity = top.intent.getComponent();
5455                    if (top.thumbHolder != null) {
5456                        ci.description = top.thumbHolder.lastDescription;
5457                    }
5458                    ci.numActivities = numActivities;
5459                    ci.numRunning = numRunning;
5460                    //System.out.println(
5461                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5462                    if (ci.thumbnail == null && receiver != null) {
5463                        if (localLOGV) Slog.v(
5464                            TAG, "State=" + top.state + "Idle=" + top.idle
5465                            + " app=" + top.app
5466                            + " thr=" + (top.app != null ? top.app.thread : null));
5467                        if (top.state == ActivityState.RESUMED
5468                                || top.state == ActivityState.PAUSING) {
5469                            if (top.idle && top.app != null
5470                                && top.app.thread != null) {
5471                                topRecord = top;
5472                                topThumbnail = top.app.thread;
5473                            } else {
5474                                top.thumbnailNeeded = true;
5475                            }
5476                        }
5477                        if (pending == null) {
5478                            pending = new PendingThumbnailsRecord(receiver);
5479                        }
5480                        pending.pendingRecords.add(top);
5481                    }
5482                    list.add(ci);
5483                    maxNum--;
5484                    top = null;
5485                }
5486            }
5487
5488            if (pending != null) {
5489                mPendingThumbnails.add(pending);
5490            }
5491        }
5492
5493        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5494
5495        if (topThumbnail != null) {
5496            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5497            try {
5498                topThumbnail.requestThumbnail(topRecord.appToken);
5499            } catch (Exception e) {
5500                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5501                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5502            }
5503        }
5504
5505        if (pending == null && receiver != null) {
5506            // In this case all thumbnails were available and the client
5507            // is being asked to be told when the remaining ones come in...
5508            // which is unusually, since the top-most currently running
5509            // activity should never have a canned thumbnail!  Oh well.
5510            try {
5511                receiver.finished();
5512            } catch (RemoteException ex) {
5513            }
5514        }
5515
5516        return list;
5517    }
5518
5519    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5520            int flags, int userId) {
5521        final int callingUid = Binder.getCallingUid();
5522        if (userId != UserId.getCallingUserId()) {
5523            // Check if the caller is holding permissions for cross-user requests.
5524            if (checkComponentPermission(
5525                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5526                    Binder.getCallingPid(), callingUid, -1, true)
5527                    != PackageManager.PERMISSION_GRANTED) {
5528                String msg = "Permission Denial: "
5529                        + "Request to get recent tasks for user " + userId
5530                        + " but is calling from user " + UserId.getUserId(callingUid)
5531                        + "; this requires "
5532                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5533                Slog.w(TAG, msg);
5534                throw new SecurityException(msg);
5535            } else {
5536                if (userId == UserId.USER_CURRENT) {
5537                    userId = mCurrentUserId;
5538                }
5539            }
5540        }
5541
5542        synchronized (this) {
5543            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5544                    "getRecentTasks()");
5545            final boolean detailed = checkCallingPermission(
5546                    android.Manifest.permission.GET_DETAILED_TASKS)
5547                    == PackageManager.PERMISSION_GRANTED;
5548
5549            IPackageManager pm = AppGlobals.getPackageManager();
5550
5551            final int N = mRecentTasks.size();
5552            ArrayList<ActivityManager.RecentTaskInfo> res
5553                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5554                            maxNum < N ? maxNum : N);
5555            for (int i=0; i<N && maxNum > 0; i++) {
5556                TaskRecord tr = mRecentTasks.get(i);
5557                // Only add calling user's recent tasks
5558                if (tr.userId != userId) continue;
5559                // Return the entry if desired by the caller.  We always return
5560                // the first entry, because callers always expect this to be the
5561                // foreground app.  We may filter others if the caller has
5562                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5563                // we should exclude the entry.
5564
5565                if (i == 0
5566                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5567                        || (tr.intent == null)
5568                        || ((tr.intent.getFlags()
5569                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5570                    ActivityManager.RecentTaskInfo rti
5571                            = new ActivityManager.RecentTaskInfo();
5572                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5573                    rti.persistentId = tr.taskId;
5574                    rti.baseIntent = new Intent(
5575                            tr.intent != null ? tr.intent : tr.affinityIntent);
5576                    if (!detailed) {
5577                        rti.baseIntent.replaceExtras((Bundle)null);
5578                    }
5579                    rti.origActivity = tr.origActivity;
5580                    rti.description = tr.lastDescription;
5581
5582                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5583                        // Check whether this activity is currently available.
5584                        try {
5585                            if (rti.origActivity != null) {
5586                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5587                                        == null) {
5588                                    continue;
5589                                }
5590                            } else if (rti.baseIntent != null) {
5591                                if (pm.queryIntentActivities(rti.baseIntent,
5592                                        null, 0, userId) == null) {
5593                                    continue;
5594                                }
5595                            }
5596                        } catch (RemoteException e) {
5597                            // Will never happen.
5598                        }
5599                    }
5600
5601                    res.add(rti);
5602                    maxNum--;
5603                }
5604            }
5605            return res;
5606        }
5607    }
5608
5609    private TaskRecord taskForIdLocked(int id) {
5610        final int N = mRecentTasks.size();
5611        for (int i=0; i<N; i++) {
5612            TaskRecord tr = mRecentTasks.get(i);
5613            if (tr.taskId == id) {
5614                return tr;
5615            }
5616        }
5617        return null;
5618    }
5619
5620    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5621        synchronized (this) {
5622            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5623                    "getTaskThumbnails()");
5624            TaskRecord tr = taskForIdLocked(id);
5625            if (tr != null) {
5626                return mMainStack.getTaskThumbnailsLocked(tr);
5627            }
5628        }
5629        return null;
5630    }
5631
5632    public boolean removeSubTask(int taskId, int subTaskIndex) {
5633        synchronized (this) {
5634            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5635                    "removeSubTask()");
5636            long ident = Binder.clearCallingIdentity();
5637            try {
5638                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5639                        true) != null;
5640            } finally {
5641                Binder.restoreCallingIdentity(ident);
5642            }
5643        }
5644    }
5645
5646    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5647        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5648        Intent baseIntent = new Intent(
5649                tr.intent != null ? tr.intent : tr.affinityIntent);
5650        ComponentName component = baseIntent.getComponent();
5651        if (component == null) {
5652            Slog.w(TAG, "Now component for base intent of task: " + tr);
5653            return;
5654        }
5655
5656        // Find any running services associated with this app.
5657        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5658
5659        if (killProcesses) {
5660            // Find any running processes associated with this app.
5661            final String pkg = component.getPackageName();
5662            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5663            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5664            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5665                for (int i=0; i<uids.size(); i++) {
5666                    ProcessRecord proc = uids.valueAt(i);
5667                    if (proc.userId != tr.userId) {
5668                        continue;
5669                    }
5670                    if (!proc.pkgList.contains(pkg)) {
5671                        continue;
5672                    }
5673                    procs.add(proc);
5674                }
5675            }
5676
5677            // Kill the running processes.
5678            for (int i=0; i<procs.size(); i++) {
5679                ProcessRecord pr = procs.get(i);
5680                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5681                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5682                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5683                            pr.processName, pr.setAdj, "remove task");
5684                    pr.killedBackground = true;
5685                    Process.killProcessQuiet(pr.pid);
5686                } else {
5687                    pr.waitingToKill = "remove task";
5688                }
5689            }
5690        }
5691    }
5692
5693    public boolean removeTask(int taskId, int flags) {
5694        synchronized (this) {
5695            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5696                    "removeTask()");
5697            long ident = Binder.clearCallingIdentity();
5698            try {
5699                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5700                        false);
5701                if (r != null) {
5702                    mRecentTasks.remove(r.task);
5703                    cleanUpRemovedTaskLocked(r.task, flags);
5704                    return true;
5705                } else {
5706                    TaskRecord tr = null;
5707                    int i=0;
5708                    while (i < mRecentTasks.size()) {
5709                        TaskRecord t = mRecentTasks.get(i);
5710                        if (t.taskId == taskId) {
5711                            tr = t;
5712                            break;
5713                        }
5714                        i++;
5715                    }
5716                    if (tr != null) {
5717                        if (tr.numActivities <= 0) {
5718                            // Caller is just removing a recent task that is
5719                            // not actively running.  That is easy!
5720                            mRecentTasks.remove(i);
5721                            cleanUpRemovedTaskLocked(tr, flags);
5722                            return true;
5723                        } else {
5724                            Slog.w(TAG, "removeTask: task " + taskId
5725                                    + " does not have activities to remove, "
5726                                    + " but numActivities=" + tr.numActivities
5727                                    + ": " + tr);
5728                        }
5729                    }
5730                }
5731            } finally {
5732                Binder.restoreCallingIdentity(ident);
5733            }
5734        }
5735        return false;
5736    }
5737
5738    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5739        int j;
5740        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5741        TaskRecord jt = startTask;
5742
5743        // First look backwards
5744        for (j=startIndex-1; j>=0; j--) {
5745            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5746            if (r.task != jt) {
5747                jt = r.task;
5748                if (affinity.equals(jt.affinity)) {
5749                    return j;
5750                }
5751            }
5752        }
5753
5754        // Now look forwards
5755        final int N = mMainStack.mHistory.size();
5756        jt = startTask;
5757        for (j=startIndex+1; j<N; j++) {
5758            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5759            if (r.task != jt) {
5760                if (affinity.equals(jt.affinity)) {
5761                    return j;
5762                }
5763                jt = r.task;
5764            }
5765        }
5766
5767        // Might it be at the top?
5768        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5769            return N-1;
5770        }
5771
5772        return -1;
5773    }
5774
5775    /**
5776     * TODO: Add mController hook
5777     */
5778    public void moveTaskToFront(int task, int flags, Bundle options) {
5779        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5780                "moveTaskToFront()");
5781
5782        synchronized(this) {
5783            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5784                    Binder.getCallingUid(), "Task to front")) {
5785                ActivityOptions.abort(options);
5786                return;
5787            }
5788            final long origId = Binder.clearCallingIdentity();
5789            try {
5790                TaskRecord tr = taskForIdLocked(task);
5791                if (tr != null) {
5792                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5793                        mMainStack.mUserLeaving = true;
5794                    }
5795                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5796                        // Caller wants the home activity moved with it.  To accomplish this,
5797                        // we'll just move the home task to the top first.
5798                        mMainStack.moveHomeToFrontLocked();
5799                    }
5800                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5801                    return;
5802                }
5803                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5804                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5805                    if (hr.task.taskId == task) {
5806                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5807                            mMainStack.mUserLeaving = true;
5808                        }
5809                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5810                            // Caller wants the home activity moved with it.  To accomplish this,
5811                            // we'll just move the home task to the top first.
5812                            mMainStack.moveHomeToFrontLocked();
5813                        }
5814                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5815                        return;
5816                    }
5817                }
5818            } finally {
5819                Binder.restoreCallingIdentity(origId);
5820            }
5821            ActivityOptions.abort(options);
5822        }
5823    }
5824
5825    public void moveTaskToBack(int task) {
5826        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5827                "moveTaskToBack()");
5828
5829        synchronized(this) {
5830            if (mMainStack.mResumedActivity != null
5831                    && mMainStack.mResumedActivity.task.taskId == task) {
5832                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5833                        Binder.getCallingUid(), "Task to back")) {
5834                    return;
5835                }
5836            }
5837            final long origId = Binder.clearCallingIdentity();
5838            mMainStack.moveTaskToBackLocked(task, null);
5839            Binder.restoreCallingIdentity(origId);
5840        }
5841    }
5842
5843    /**
5844     * Moves an activity, and all of the other activities within the same task, to the bottom
5845     * of the history stack.  The activity's order within the task is unchanged.
5846     *
5847     * @param token A reference to the activity we wish to move
5848     * @param nonRoot If false then this only works if the activity is the root
5849     *                of a task; if true it will work for any activity in a task.
5850     * @return Returns true if the move completed, false if not.
5851     */
5852    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5853        enforceNotIsolatedCaller("moveActivityTaskToBack");
5854        synchronized(this) {
5855            final long origId = Binder.clearCallingIdentity();
5856            int taskId = getTaskForActivityLocked(token, !nonRoot);
5857            if (taskId >= 0) {
5858                return mMainStack.moveTaskToBackLocked(taskId, null);
5859            }
5860            Binder.restoreCallingIdentity(origId);
5861        }
5862        return false;
5863    }
5864
5865    public void moveTaskBackwards(int task) {
5866        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5867                "moveTaskBackwards()");
5868
5869        synchronized(this) {
5870            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5871                    Binder.getCallingUid(), "Task backwards")) {
5872                return;
5873            }
5874            final long origId = Binder.clearCallingIdentity();
5875            moveTaskBackwardsLocked(task);
5876            Binder.restoreCallingIdentity(origId);
5877        }
5878    }
5879
5880    private final void moveTaskBackwardsLocked(int task) {
5881        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5882    }
5883
5884    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5885        synchronized(this) {
5886            return getTaskForActivityLocked(token, onlyRoot);
5887        }
5888    }
5889
5890    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5891        final int N = mMainStack.mHistory.size();
5892        TaskRecord lastTask = null;
5893        for (int i=0; i<N; i++) {
5894            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5895            if (r.appToken == token) {
5896                if (!onlyRoot || lastTask != r.task) {
5897                    return r.task.taskId;
5898                }
5899                return -1;
5900            }
5901            lastTask = r.task;
5902        }
5903
5904        return -1;
5905    }
5906
5907    // =========================================================
5908    // THUMBNAILS
5909    // =========================================================
5910
5911    public void reportThumbnail(IBinder token,
5912            Bitmap thumbnail, CharSequence description) {
5913        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5914        final long origId = Binder.clearCallingIdentity();
5915        sendPendingThumbnail(null, token, thumbnail, description, true);
5916        Binder.restoreCallingIdentity(origId);
5917    }
5918
5919    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5920            Bitmap thumbnail, CharSequence description, boolean always) {
5921        TaskRecord task = null;
5922        ArrayList receivers = null;
5923
5924        //System.out.println("Send pending thumbnail: " + r);
5925
5926        synchronized(this) {
5927            if (r == null) {
5928                r = mMainStack.isInStackLocked(token);
5929                if (r == null) {
5930                    return;
5931                }
5932            }
5933            if (thumbnail == null && r.thumbHolder != null) {
5934                thumbnail = r.thumbHolder.lastThumbnail;
5935                description = r.thumbHolder.lastDescription;
5936            }
5937            if (thumbnail == null && !always) {
5938                // If there is no thumbnail, and this entry is not actually
5939                // going away, then abort for now and pick up the next
5940                // thumbnail we get.
5941                return;
5942            }
5943            task = r.task;
5944
5945            int N = mPendingThumbnails.size();
5946            int i=0;
5947            while (i<N) {
5948                PendingThumbnailsRecord pr =
5949                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5950                //System.out.println("Looking in " + pr.pendingRecords);
5951                if (pr.pendingRecords.remove(r)) {
5952                    if (receivers == null) {
5953                        receivers = new ArrayList();
5954                    }
5955                    receivers.add(pr);
5956                    if (pr.pendingRecords.size() == 0) {
5957                        pr.finished = true;
5958                        mPendingThumbnails.remove(i);
5959                        N--;
5960                        continue;
5961                    }
5962                }
5963                i++;
5964            }
5965        }
5966
5967        if (receivers != null) {
5968            final int N = receivers.size();
5969            for (int i=0; i<N; i++) {
5970                try {
5971                    PendingThumbnailsRecord pr =
5972                        (PendingThumbnailsRecord)receivers.get(i);
5973                    pr.receiver.newThumbnail(
5974                        task != null ? task.taskId : -1, thumbnail, description);
5975                    if (pr.finished) {
5976                        pr.receiver.finished();
5977                    }
5978                } catch (Exception e) {
5979                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5980                }
5981            }
5982        }
5983    }
5984
5985    // =========================================================
5986    // CONTENT PROVIDERS
5987    // =========================================================
5988
5989    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5990        List<ProviderInfo> providers = null;
5991        try {
5992            providers = AppGlobals.getPackageManager().
5993                queryContentProviders(app.processName, app.uid,
5994                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5995        } catch (RemoteException ex) {
5996        }
5997        if (DEBUG_MU)
5998            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
5999        int userId = app.userId;
6000        if (providers != null) {
6001            int N = providers.size();
6002            for (int i=0; i<N; i++) {
6003                ProviderInfo cpi =
6004                    (ProviderInfo)providers.get(i);
6005                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6006                        cpi.name, cpi.flags);
6007                if (singleton && UserId.getUserId(app.uid) != 0) {
6008                    // This is a singleton provider, but a user besides the
6009                    // default user is asking to initialize a process it runs
6010                    // in...  well, no, it doesn't actually run in this process,
6011                    // it runs in the process of the default user.  Get rid of it.
6012                    providers.remove(i);
6013                    N--;
6014                    continue;
6015                }
6016
6017                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6018                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6019                if (cpr == null) {
6020                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6021                    mProviderMap.putProviderByClass(comp, cpr);
6022                }
6023                if (DEBUG_MU)
6024                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6025                app.pubProviders.put(cpi.name, cpr);
6026                app.addPackage(cpi.applicationInfo.packageName);
6027                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6028            }
6029        }
6030        return providers;
6031    }
6032
6033    /**
6034     * Check if {@link ProcessRecord} has a possible chance at accessing the
6035     * given {@link ProviderInfo}. Final permission checking is always done
6036     * in {@link ContentProvider}.
6037     */
6038    private final String checkContentProviderPermissionLocked(
6039            ProviderInfo cpi, ProcessRecord r) {
6040        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6041        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6042        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6043                cpi.applicationInfo.uid, cpi.exported)
6044                == PackageManager.PERMISSION_GRANTED) {
6045            return null;
6046        }
6047        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6048                cpi.applicationInfo.uid, cpi.exported)
6049                == PackageManager.PERMISSION_GRANTED) {
6050            return null;
6051        }
6052
6053        PathPermission[] pps = cpi.pathPermissions;
6054        if (pps != null) {
6055            int i = pps.length;
6056            while (i > 0) {
6057                i--;
6058                PathPermission pp = pps[i];
6059                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6060                        cpi.applicationInfo.uid, cpi.exported)
6061                        == PackageManager.PERMISSION_GRANTED) {
6062                    return null;
6063                }
6064                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6065                        cpi.applicationInfo.uid, cpi.exported)
6066                        == PackageManager.PERMISSION_GRANTED) {
6067                    return null;
6068                }
6069            }
6070        }
6071
6072        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6073        if (perms != null) {
6074            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6075                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6076                    return null;
6077                }
6078            }
6079        }
6080
6081        String msg;
6082        if (!cpi.exported) {
6083            msg = "Permission Denial: opening provider " + cpi.name
6084                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6085                    + ", uid=" + callingUid + ") that is not exported from uid "
6086                    + cpi.applicationInfo.uid;
6087        } else {
6088            msg = "Permission Denial: opening provider " + cpi.name
6089                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6090                    + ", uid=" + callingUid + ") requires "
6091                    + cpi.readPermission + " or " + cpi.writePermission;
6092        }
6093        Slog.w(TAG, msg);
6094        return msg;
6095    }
6096
6097    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6098            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6099        if (r != null) {
6100            for (int i=0; i<r.conProviders.size(); i++) {
6101                ContentProviderConnection conn = r.conProviders.get(i);
6102                if (conn.provider == cpr) {
6103                    if (DEBUG_PROVIDER) Slog.v(TAG,
6104                            "Adding provider requested by "
6105                            + r.processName + " from process "
6106                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6107                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6108                    if (stable) {
6109                        conn.stableCount++;
6110                        conn.numStableIncs++;
6111                    } else {
6112                        conn.unstableCount++;
6113                        conn.numUnstableIncs++;
6114                    }
6115                    return conn;
6116                }
6117            }
6118            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6119            if (stable) {
6120                conn.stableCount = 1;
6121                conn.numStableIncs = 1;
6122            } else {
6123                conn.unstableCount = 1;
6124                conn.numUnstableIncs = 1;
6125            }
6126            cpr.connections.add(conn);
6127            r.conProviders.add(conn);
6128            return conn;
6129        }
6130        cpr.addExternalProcessHandleLocked(externalProcessToken);
6131        return null;
6132    }
6133
6134    boolean decProviderCountLocked(ContentProviderConnection conn,
6135            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6136        if (conn != null) {
6137            cpr = conn.provider;
6138            if (DEBUG_PROVIDER) Slog.v(TAG,
6139                    "Removing provider requested by "
6140                    + conn.client.processName + " from process "
6141                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6142                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6143            if (stable) {
6144                conn.stableCount--;
6145            } else {
6146                conn.unstableCount--;
6147            }
6148            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6149                cpr.connections.remove(conn);
6150                conn.client.conProviders.remove(conn);
6151                return true;
6152            }
6153            return false;
6154        }
6155        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6156        return false;
6157    }
6158
6159    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6160            String name, IBinder token, boolean stable) {
6161        ContentProviderRecord cpr;
6162        ContentProviderConnection conn = null;
6163        ProviderInfo cpi = null;
6164
6165        synchronized(this) {
6166            ProcessRecord r = null;
6167            if (caller != null) {
6168                r = getRecordForAppLocked(caller);
6169                if (r == null) {
6170                    throw new SecurityException(
6171                            "Unable to find app for caller " + caller
6172                          + " (pid=" + Binder.getCallingPid()
6173                          + ") when getting content provider " + name);
6174                }
6175            }
6176
6177            // First check if this content provider has been published...
6178            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6179            cpr = mProviderMap.getProviderByName(name, userId);
6180            boolean providerRunning = cpr != null;
6181            if (providerRunning) {
6182                cpi = cpr.info;
6183                String msg;
6184                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6185                    throw new SecurityException(msg);
6186                }
6187
6188                if (r != null && cpr.canRunHere(r)) {
6189                    // This provider has been published or is in the process
6190                    // of being published...  but it is also allowed to run
6191                    // in the caller's process, so don't make a connection
6192                    // and just let the caller instantiate its own instance.
6193                    ContentProviderHolder holder = cpr.newHolder(null);
6194                    // don't give caller the provider object, it needs
6195                    // to make its own.
6196                    holder.provider = null;
6197                    return holder;
6198                }
6199
6200                final long origId = Binder.clearCallingIdentity();
6201
6202                // In this case the provider instance already exists, so we can
6203                // return it right away.
6204                conn = incProviderCountLocked(r, cpr, token, stable);
6205                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6206                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6207                        // If this is a perceptible app accessing the provider,
6208                        // make sure to count it as being accessed and thus
6209                        // back up on the LRU list.  This is good because
6210                        // content providers are often expensive to start.
6211                        updateLruProcessLocked(cpr.proc, false, true);
6212                    }
6213                }
6214
6215                if (cpr.proc != null) {
6216                    if (false) {
6217                        if (cpr.name.flattenToShortString().equals(
6218                                "com.android.providers.calendar/.CalendarProvider2")) {
6219                            Slog.v(TAG, "****************** KILLING "
6220                                + cpr.name.flattenToShortString());
6221                            Process.killProcess(cpr.proc.pid);
6222                        }
6223                    }
6224                    boolean success = updateOomAdjLocked(cpr.proc);
6225                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6226                    // NOTE: there is still a race here where a signal could be
6227                    // pending on the process even though we managed to update its
6228                    // adj level.  Not sure what to do about this, but at least
6229                    // the race is now smaller.
6230                    if (!success) {
6231                        // Uh oh...  it looks like the provider's process
6232                        // has been killed on us.  We need to wait for a new
6233                        // process to be started, and make sure its death
6234                        // doesn't kill our process.
6235                        Slog.i(TAG,
6236                                "Existing provider " + cpr.name.flattenToShortString()
6237                                + " is crashing; detaching " + r);
6238                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6239                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6240                        if (!lastRef) {
6241                            // This wasn't the last ref our process had on
6242                            // the provider...  we have now been killed, bail.
6243                            return null;
6244                        }
6245                        providerRunning = false;
6246                        conn = null;
6247                    }
6248                }
6249
6250                Binder.restoreCallingIdentity(origId);
6251            }
6252
6253            boolean singleton;
6254            if (!providerRunning) {
6255                try {
6256                    cpi = AppGlobals.getPackageManager().
6257                        resolveContentProvider(name,
6258                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6259                } catch (RemoteException ex) {
6260                }
6261                if (cpi == null) {
6262                    return null;
6263                }
6264                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6265                        cpi.name, cpi.flags);
6266                if (singleton) {
6267                    userId = 0;
6268                }
6269                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6270
6271                String msg;
6272                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6273                    throw new SecurityException(msg);
6274                }
6275
6276                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6277                        && !cpi.processName.equals("system")) {
6278                    // If this content provider does not run in the system
6279                    // process, and the system is not yet ready to run other
6280                    // processes, then fail fast instead of hanging.
6281                    throw new IllegalArgumentException(
6282                            "Attempt to launch content provider before system ready");
6283                }
6284
6285                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6286                cpr = mProviderMap.getProviderByClass(comp, userId);
6287                final boolean firstClass = cpr == null;
6288                if (firstClass) {
6289                    try {
6290                        ApplicationInfo ai =
6291                            AppGlobals.getPackageManager().
6292                                getApplicationInfo(
6293                                        cpi.applicationInfo.packageName,
6294                                        STOCK_PM_FLAGS, userId);
6295                        if (ai == null) {
6296                            Slog.w(TAG, "No package info for content provider "
6297                                    + cpi.name);
6298                            return null;
6299                        }
6300                        ai = getAppInfoForUser(ai, userId);
6301                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6302                    } catch (RemoteException ex) {
6303                        // pm is in same process, this will never happen.
6304                    }
6305                }
6306
6307                if (r != null && cpr.canRunHere(r)) {
6308                    // If this is a multiprocess provider, then just return its
6309                    // info and allow the caller to instantiate it.  Only do
6310                    // this if the provider is the same user as the caller's
6311                    // process, or can run as root (so can be in any process).
6312                    return cpr.newHolder(null);
6313                }
6314
6315                if (DEBUG_PROVIDER) {
6316                    RuntimeException e = new RuntimeException("here");
6317                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6318                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6319                }
6320
6321                // This is single process, and our app is now connecting to it.
6322                // See if we are already in the process of launching this
6323                // provider.
6324                final int N = mLaunchingProviders.size();
6325                int i;
6326                for (i=0; i<N; i++) {
6327                    if (mLaunchingProviders.get(i) == cpr) {
6328                        break;
6329                    }
6330                }
6331
6332                // If the provider is not already being launched, then get it
6333                // started.
6334                if (i >= N) {
6335                    final long origId = Binder.clearCallingIdentity();
6336
6337                    try {
6338                        // Content provider is now in use, its package can't be stopped.
6339                        try {
6340                            AppGlobals.getPackageManager().setPackageStoppedState(
6341                                    cpr.appInfo.packageName, false, userId);
6342                        } catch (RemoteException e) {
6343                        } catch (IllegalArgumentException e) {
6344                            Slog.w(TAG, "Failed trying to unstop package "
6345                                    + cpr.appInfo.packageName + ": " + e);
6346                        }
6347
6348                        ProcessRecord proc = startProcessLocked(cpi.processName,
6349                                cpr.appInfo, false, 0, "content provider",
6350                                new ComponentName(cpi.applicationInfo.packageName,
6351                                        cpi.name), false, false);
6352                        if (proc == null) {
6353                            Slog.w(TAG, "Unable to launch app "
6354                                    + cpi.applicationInfo.packageName + "/"
6355                                    + cpi.applicationInfo.uid + " for provider "
6356                                    + name + ": process is bad");
6357                            return null;
6358                        }
6359                        cpr.launchingApp = proc;
6360                        mLaunchingProviders.add(cpr);
6361                    } finally {
6362                        Binder.restoreCallingIdentity(origId);
6363                    }
6364                }
6365
6366                // Make sure the provider is published (the same provider class
6367                // may be published under multiple names).
6368                if (firstClass) {
6369                    mProviderMap.putProviderByClass(comp, cpr);
6370                }
6371
6372                mProviderMap.putProviderByName(name, cpr);
6373                conn = incProviderCountLocked(r, cpr, token, stable);
6374                if (conn != null) {
6375                    conn.waiting = true;
6376                }
6377            }
6378        }
6379
6380        // Wait for the provider to be published...
6381        synchronized (cpr) {
6382            while (cpr.provider == null) {
6383                if (cpr.launchingApp == null) {
6384                    Slog.w(TAG, "Unable to launch app "
6385                            + cpi.applicationInfo.packageName + "/"
6386                            + cpi.applicationInfo.uid + " for provider "
6387                            + name + ": launching app became null");
6388                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6389                            cpi.applicationInfo.packageName,
6390                            cpi.applicationInfo.uid, name);
6391                    return null;
6392                }
6393                try {
6394                    if (DEBUG_MU) {
6395                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6396                                + cpr.launchingApp);
6397                    }
6398                    if (conn != null) {
6399                        conn.waiting = true;
6400                    }
6401                    cpr.wait();
6402                } catch (InterruptedException ex) {
6403                } finally {
6404                    if (conn != null) {
6405                        conn.waiting = false;
6406                    }
6407                }
6408            }
6409        }
6410        return cpr != null ? cpr.newHolder(conn) : null;
6411    }
6412
6413    public final ContentProviderHolder getContentProvider(
6414            IApplicationThread caller, String name, boolean stable) {
6415        enforceNotIsolatedCaller("getContentProvider");
6416        if (caller == null) {
6417            String msg = "null IApplicationThread when getting content provider "
6418                    + name;
6419            Slog.w(TAG, msg);
6420            throw new SecurityException(msg);
6421        }
6422
6423        return getContentProviderImpl(caller, name, null, stable);
6424    }
6425
6426    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6427        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6428            "Do not have permission in call getContentProviderExternal()");
6429        return getContentProviderExternalUnchecked(name, token);
6430    }
6431
6432    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6433        return getContentProviderImpl(null, name, token, true);
6434    }
6435
6436    /**
6437     * Drop a content provider from a ProcessRecord's bookkeeping
6438     * @param cpr
6439     */
6440    public void removeContentProvider(IBinder connection, boolean stable) {
6441        enforceNotIsolatedCaller("removeContentProvider");
6442        synchronized (this) {
6443            ContentProviderConnection conn;
6444            try {
6445                conn = (ContentProviderConnection)connection;
6446            } catch (ClassCastException e) {
6447                String msg ="removeContentProvider: " + connection
6448                        + " not a ContentProviderConnection";
6449                Slog.w(TAG, msg);
6450                throw new IllegalArgumentException(msg);
6451            }
6452            if (conn == null) {
6453                throw new NullPointerException("connection is null");
6454            }
6455            if (decProviderCountLocked(conn, null, null, stable)) {
6456                updateOomAdjLocked();
6457            }
6458        }
6459    }
6460
6461    public void removeContentProviderExternal(String name, IBinder token) {
6462        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6463            "Do not have permission in call removeContentProviderExternal()");
6464        removeContentProviderExternalUnchecked(name, token);
6465    }
6466
6467    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6468        synchronized (this) {
6469            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6470                    Binder.getOrigCallingUser());
6471            if(cpr == null) {
6472                //remove from mProvidersByClass
6473                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6474                return;
6475            }
6476
6477            //update content provider record entry info
6478            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6479            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6480                    Binder.getOrigCallingUser());
6481            if (localCpr.hasExternalProcessHandles()) {
6482                if (localCpr.removeExternalProcessHandleLocked(token)) {
6483                    updateOomAdjLocked();
6484                } else {
6485                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6486                            + " with no external reference for token: "
6487                            + token + ".");
6488                }
6489            } else {
6490                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6491                        + " with no external references.");
6492            }
6493        }
6494    }
6495
6496    public final void publishContentProviders(IApplicationThread caller,
6497            List<ContentProviderHolder> providers) {
6498        if (providers == null) {
6499            return;
6500        }
6501
6502        enforceNotIsolatedCaller("publishContentProviders");
6503        synchronized (this) {
6504            final ProcessRecord r = getRecordForAppLocked(caller);
6505            if (DEBUG_MU)
6506                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6507            if (r == null) {
6508                throw new SecurityException(
6509                        "Unable to find app for caller " + caller
6510                      + " (pid=" + Binder.getCallingPid()
6511                      + ") when publishing content providers");
6512            }
6513
6514            final long origId = Binder.clearCallingIdentity();
6515
6516            final int N = providers.size();
6517            for (int i=0; i<N; i++) {
6518                ContentProviderHolder src = providers.get(i);
6519                if (src == null || src.info == null || src.provider == null) {
6520                    continue;
6521                }
6522                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6523                if (DEBUG_MU)
6524                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6525                if (dst != null) {
6526                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6527                    mProviderMap.putProviderByClass(comp, dst);
6528                    String names[] = dst.info.authority.split(";");
6529                    for (int j = 0; j < names.length; j++) {
6530                        mProviderMap.putProviderByName(names[j], dst);
6531                    }
6532
6533                    int NL = mLaunchingProviders.size();
6534                    int j;
6535                    for (j=0; j<NL; j++) {
6536                        if (mLaunchingProviders.get(j) == dst) {
6537                            mLaunchingProviders.remove(j);
6538                            j--;
6539                            NL--;
6540                        }
6541                    }
6542                    synchronized (dst) {
6543                        dst.provider = src.provider;
6544                        dst.proc = r;
6545                        dst.notifyAll();
6546                    }
6547                    updateOomAdjLocked(r);
6548                }
6549            }
6550
6551            Binder.restoreCallingIdentity(origId);
6552        }
6553    }
6554
6555    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6556        ContentProviderConnection conn;
6557        try {
6558            conn = (ContentProviderConnection)connection;
6559        } catch (ClassCastException e) {
6560            String msg ="refContentProvider: " + connection
6561                    + " not a ContentProviderConnection";
6562            Slog.w(TAG, msg);
6563            throw new IllegalArgumentException(msg);
6564        }
6565        if (conn == null) {
6566            throw new NullPointerException("connection is null");
6567        }
6568
6569        synchronized (this) {
6570            if (stable > 0) {
6571                conn.numStableIncs += stable;
6572            }
6573            stable = conn.stableCount + stable;
6574            if (stable < 0) {
6575                throw new IllegalStateException("stableCount < 0: " + stable);
6576            }
6577
6578            if (unstable > 0) {
6579                conn.numUnstableIncs += unstable;
6580            }
6581            unstable = conn.unstableCount + unstable;
6582            if (unstable < 0) {
6583                throw new IllegalStateException("unstableCount < 0: " + unstable);
6584            }
6585
6586            if ((stable+unstable) <= 0) {
6587                throw new IllegalStateException("ref counts can't go to zero here: stable="
6588                        + stable + " unstable=" + unstable);
6589            }
6590            conn.stableCount = stable;
6591            conn.unstableCount = unstable;
6592            return !conn.dead;
6593        }
6594    }
6595
6596    public void unstableProviderDied(IBinder connection) {
6597        ContentProviderConnection conn;
6598        try {
6599            conn = (ContentProviderConnection)connection;
6600        } catch (ClassCastException e) {
6601            String msg ="refContentProvider: " + connection
6602                    + " not a ContentProviderConnection";
6603            Slog.w(TAG, msg);
6604            throw new IllegalArgumentException(msg);
6605        }
6606        if (conn == null) {
6607            throw new NullPointerException("connection is null");
6608        }
6609
6610        // Safely retrieve the content provider associated with the connection.
6611        IContentProvider provider;
6612        synchronized (this) {
6613            provider = conn.provider.provider;
6614        }
6615
6616        if (provider == null) {
6617            // Um, yeah, we're way ahead of you.
6618            return;
6619        }
6620
6621        // Make sure the caller is being honest with us.
6622        if (provider.asBinder().pingBinder()) {
6623            // Er, no, still looks good to us.
6624            synchronized (this) {
6625                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6626                        + " says " + conn + " died, but we don't agree");
6627                return;
6628            }
6629        }
6630
6631        // Well look at that!  It's dead!
6632        synchronized (this) {
6633            if (conn.provider.provider != provider) {
6634                // But something changed...  good enough.
6635                return;
6636            }
6637
6638            ProcessRecord proc = conn.provider.proc;
6639            if (proc == null || proc.thread == null) {
6640                // Seems like the process is already cleaned up.
6641                return;
6642            }
6643
6644            // As far as we're concerned, this is just like receiving a
6645            // death notification...  just a bit prematurely.
6646            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6647                    + ") early provider death");
6648            final long ident = Binder.clearCallingIdentity();
6649            try {
6650                appDiedLocked(proc, proc.pid, proc.thread);
6651            } finally {
6652                Binder.restoreCallingIdentity(ident);
6653            }
6654        }
6655    }
6656
6657    public static final void installSystemProviders() {
6658        List<ProviderInfo> providers;
6659        synchronized (mSelf) {
6660            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6661            providers = mSelf.generateApplicationProvidersLocked(app);
6662            if (providers != null) {
6663                for (int i=providers.size()-1; i>=0; i--) {
6664                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6665                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6666                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6667                                + ": not system .apk");
6668                        providers.remove(i);
6669                    }
6670                }
6671            }
6672        }
6673        if (providers != null) {
6674            mSystemThread.installSystemProviders(providers);
6675        }
6676
6677        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6678
6679        mSelf.mUsageStatsService.monitorPackages();
6680    }
6681
6682    /**
6683     * Allows app to retrieve the MIME type of a URI without having permission
6684     * to access its content provider.
6685     *
6686     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6687     *
6688     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6689     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6690     */
6691    public String getProviderMimeType(Uri uri) {
6692        enforceNotIsolatedCaller("getProviderMimeType");
6693        final String name = uri.getAuthority();
6694        final long ident = Binder.clearCallingIdentity();
6695        ContentProviderHolder holder = null;
6696
6697        try {
6698            holder = getContentProviderExternalUnchecked(name, null);
6699            if (holder != null) {
6700                return holder.provider.getType(uri);
6701            }
6702        } catch (RemoteException e) {
6703            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6704            return null;
6705        } finally {
6706            if (holder != null) {
6707                removeContentProviderExternalUnchecked(name, null);
6708            }
6709            Binder.restoreCallingIdentity(ident);
6710        }
6711
6712        return null;
6713    }
6714
6715    // =========================================================
6716    // GLOBAL MANAGEMENT
6717    // =========================================================
6718
6719    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6720            ApplicationInfo info, String customProcess, boolean isolated) {
6721        String proc = customProcess != null ? customProcess : info.processName;
6722        BatteryStatsImpl.Uid.Proc ps = null;
6723        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6724        int uid = info.uid;
6725        if (isolated) {
6726            int userId = UserId.getUserId(uid);
6727            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6728            uid = 0;
6729            while (true) {
6730                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6731                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6732                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6733                }
6734                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6735                mNextIsolatedProcessUid++;
6736                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6737                    // No process for this uid, use it.
6738                    break;
6739                }
6740                stepsLeft--;
6741                if (stepsLeft <= 0) {
6742                    return null;
6743                }
6744            }
6745        }
6746        synchronized (stats) {
6747            ps = stats.getProcessStatsLocked(info.uid, proc);
6748        }
6749        return new ProcessRecord(ps, thread, info, proc, uid);
6750    }
6751
6752    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6753        ProcessRecord app;
6754        if (!isolated) {
6755            app = getProcessRecordLocked(info.processName, info.uid);
6756        } else {
6757            app = null;
6758        }
6759
6760        if (app == null) {
6761            app = newProcessRecordLocked(null, info, null, isolated);
6762            mProcessNames.put(info.processName, app.uid, app);
6763            if (isolated) {
6764                mIsolatedProcesses.put(app.uid, app);
6765            }
6766            updateLruProcessLocked(app, true, true);
6767        }
6768
6769        // This package really, really can not be stopped.
6770        try {
6771            AppGlobals.getPackageManager().setPackageStoppedState(
6772                    info.packageName, false, UserId.getUserId(app.uid));
6773        } catch (RemoteException e) {
6774        } catch (IllegalArgumentException e) {
6775            Slog.w(TAG, "Failed trying to unstop package "
6776                    + info.packageName + ": " + e);
6777        }
6778
6779        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6780                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6781            app.persistent = true;
6782            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6783        }
6784        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6785            mPersistentStartingProcesses.add(app);
6786            startProcessLocked(app, "added application", app.processName);
6787        }
6788
6789        return app;
6790    }
6791
6792    public void unhandledBack() {
6793        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6794                "unhandledBack()");
6795
6796        synchronized(this) {
6797            int count = mMainStack.mHistory.size();
6798            if (DEBUG_SWITCH) Slog.d(
6799                TAG, "Performing unhandledBack(): stack size = " + count);
6800            if (count > 1) {
6801                final long origId = Binder.clearCallingIdentity();
6802                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6803                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6804                Binder.restoreCallingIdentity(origId);
6805            }
6806        }
6807    }
6808
6809    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6810        enforceNotIsolatedCaller("openContentUri");
6811        String name = uri.getAuthority();
6812        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6813        ParcelFileDescriptor pfd = null;
6814        if (cph != null) {
6815            // We record the binder invoker's uid in thread-local storage before
6816            // going to the content provider to open the file.  Later, in the code
6817            // that handles all permissions checks, we look for this uid and use
6818            // that rather than the Activity Manager's own uid.  The effect is that
6819            // we do the check against the caller's permissions even though it looks
6820            // to the content provider like the Activity Manager itself is making
6821            // the request.
6822            sCallerIdentity.set(new Identity(
6823                    Binder.getCallingPid(), Binder.getCallingUid()));
6824            try {
6825                pfd = cph.provider.openFile(uri, "r");
6826            } catch (FileNotFoundException e) {
6827                // do nothing; pfd will be returned null
6828            } finally {
6829                // Ensure that whatever happens, we clean up the identity state
6830                sCallerIdentity.remove();
6831            }
6832
6833            // We've got the fd now, so we're done with the provider.
6834            removeContentProviderExternalUnchecked(name, null);
6835        } else {
6836            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6837        }
6838        return pfd;
6839    }
6840
6841    // Actually is sleeping or shutting down or whatever else in the future
6842    // is an inactive state.
6843    public boolean isSleeping() {
6844        return mSleeping || mShuttingDown;
6845    }
6846
6847    public void goingToSleep() {
6848        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6849                != PackageManager.PERMISSION_GRANTED) {
6850            throw new SecurityException("Requires permission "
6851                    + android.Manifest.permission.DEVICE_POWER);
6852        }
6853
6854        synchronized(this) {
6855            mWentToSleep = true;
6856            updateEventDispatchingLocked();
6857
6858            if (!mSleeping) {
6859                mSleeping = true;
6860                mMainStack.stopIfSleepingLocked();
6861
6862                // Initialize the wake times of all processes.
6863                checkExcessivePowerUsageLocked(false);
6864                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6865                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6866                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6867            }
6868        }
6869    }
6870
6871    public boolean shutdown(int timeout) {
6872        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6873                != PackageManager.PERMISSION_GRANTED) {
6874            throw new SecurityException("Requires permission "
6875                    + android.Manifest.permission.SHUTDOWN);
6876        }
6877
6878        boolean timedout = false;
6879
6880        synchronized(this) {
6881            mShuttingDown = true;
6882            updateEventDispatchingLocked();
6883
6884            if (mMainStack.mResumedActivity != null) {
6885                mMainStack.stopIfSleepingLocked();
6886                final long endTime = System.currentTimeMillis() + timeout;
6887                while (mMainStack.mResumedActivity != null
6888                        || mMainStack.mPausingActivity != null) {
6889                    long delay = endTime - System.currentTimeMillis();
6890                    if (delay <= 0) {
6891                        Slog.w(TAG, "Activity manager shutdown timed out");
6892                        timedout = true;
6893                        break;
6894                    }
6895                    try {
6896                        this.wait();
6897                    } catch (InterruptedException e) {
6898                    }
6899                }
6900            }
6901        }
6902
6903        mUsageStatsService.shutdown();
6904        mBatteryStatsService.shutdown();
6905
6906        return timedout;
6907    }
6908
6909    public final void activitySlept(IBinder token) {
6910        if (localLOGV) Slog.v(
6911            TAG, "Activity slept: token=" + token);
6912
6913        ActivityRecord r = null;
6914
6915        final long origId = Binder.clearCallingIdentity();
6916
6917        synchronized (this) {
6918            r = mMainStack.isInStackLocked(token);
6919            if (r != null) {
6920                mMainStack.activitySleptLocked(r);
6921            }
6922        }
6923
6924        Binder.restoreCallingIdentity(origId);
6925    }
6926
6927    private void comeOutOfSleepIfNeededLocked() {
6928        if (!mWentToSleep && !mLockScreenShown) {
6929            if (mSleeping) {
6930                mSleeping = false;
6931                mMainStack.awakeFromSleepingLocked();
6932                mMainStack.resumeTopActivityLocked(null);
6933            }
6934        }
6935    }
6936
6937    public void wakingUp() {
6938        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6939                != PackageManager.PERMISSION_GRANTED) {
6940            throw new SecurityException("Requires permission "
6941                    + android.Manifest.permission.DEVICE_POWER);
6942        }
6943
6944        synchronized(this) {
6945            mWentToSleep = false;
6946            updateEventDispatchingLocked();
6947            comeOutOfSleepIfNeededLocked();
6948        }
6949    }
6950
6951    private void updateEventDispatchingLocked() {
6952        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6953    }
6954
6955    public void setLockScreenShown(boolean shown) {
6956        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6957                != PackageManager.PERMISSION_GRANTED) {
6958            throw new SecurityException("Requires permission "
6959                    + android.Manifest.permission.DEVICE_POWER);
6960        }
6961
6962        synchronized(this) {
6963            mLockScreenShown = shown;
6964            comeOutOfSleepIfNeededLocked();
6965        }
6966    }
6967
6968    public void stopAppSwitches() {
6969        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6970                != PackageManager.PERMISSION_GRANTED) {
6971            throw new SecurityException("Requires permission "
6972                    + android.Manifest.permission.STOP_APP_SWITCHES);
6973        }
6974
6975        synchronized(this) {
6976            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6977                    + APP_SWITCH_DELAY_TIME;
6978            mDidAppSwitch = false;
6979            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6980            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6981            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6982        }
6983    }
6984
6985    public void resumeAppSwitches() {
6986        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6987                != PackageManager.PERMISSION_GRANTED) {
6988            throw new SecurityException("Requires permission "
6989                    + android.Manifest.permission.STOP_APP_SWITCHES);
6990        }
6991
6992        synchronized(this) {
6993            // Note that we don't execute any pending app switches... we will
6994            // let those wait until either the timeout, or the next start
6995            // activity request.
6996            mAppSwitchesAllowedTime = 0;
6997        }
6998    }
6999
7000    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7001            String name) {
7002        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7003            return true;
7004        }
7005
7006        final int perm = checkComponentPermission(
7007                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7008                callingUid, -1, true);
7009        if (perm == PackageManager.PERMISSION_GRANTED) {
7010            return true;
7011        }
7012
7013        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7014        return false;
7015    }
7016
7017    public void setDebugApp(String packageName, boolean waitForDebugger,
7018            boolean persistent) {
7019        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7020                "setDebugApp()");
7021
7022        // Note that this is not really thread safe if there are multiple
7023        // callers into it at the same time, but that's not a situation we
7024        // care about.
7025        if (persistent) {
7026            final ContentResolver resolver = mContext.getContentResolver();
7027            Settings.System.putString(
7028                resolver, Settings.System.DEBUG_APP,
7029                packageName);
7030            Settings.System.putInt(
7031                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7032                waitForDebugger ? 1 : 0);
7033        }
7034
7035        synchronized (this) {
7036            if (!persistent) {
7037                mOrigDebugApp = mDebugApp;
7038                mOrigWaitForDebugger = mWaitForDebugger;
7039            }
7040            mDebugApp = packageName;
7041            mWaitForDebugger = waitForDebugger;
7042            mDebugTransient = !persistent;
7043            if (packageName != null) {
7044                final long origId = Binder.clearCallingIdentity();
7045                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7046                Binder.restoreCallingIdentity(origId);
7047            }
7048        }
7049    }
7050
7051    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7052        synchronized (this) {
7053            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7054            if (!isDebuggable) {
7055                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7056                    throw new SecurityException("Process not debuggable: " + app.packageName);
7057                }
7058            }
7059
7060            mOpenGlTraceApp = processName;
7061        }
7062    }
7063
7064    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7065            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7066        synchronized (this) {
7067            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7068            if (!isDebuggable) {
7069                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7070                    throw new SecurityException("Process not debuggable: " + app.packageName);
7071                }
7072            }
7073            mProfileApp = processName;
7074            mProfileFile = profileFile;
7075            if (mProfileFd != null) {
7076                try {
7077                    mProfileFd.close();
7078                } catch (IOException e) {
7079                }
7080                mProfileFd = null;
7081            }
7082            mProfileFd = profileFd;
7083            mProfileType = 0;
7084            mAutoStopProfiler = autoStopProfiler;
7085        }
7086    }
7087
7088    public void setAlwaysFinish(boolean enabled) {
7089        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7090                "setAlwaysFinish()");
7091
7092        Settings.System.putInt(
7093                mContext.getContentResolver(),
7094                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7095
7096        synchronized (this) {
7097            mAlwaysFinishActivities = enabled;
7098        }
7099    }
7100
7101    public void setActivityController(IActivityController controller) {
7102        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7103                "setActivityController()");
7104        synchronized (this) {
7105            mController = controller;
7106        }
7107    }
7108
7109    public boolean isUserAMonkey() {
7110        // For now the fact that there is a controller implies
7111        // we have a monkey.
7112        synchronized (this) {
7113            return mController != null;
7114        }
7115    }
7116
7117    public void registerProcessObserver(IProcessObserver observer) {
7118        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7119                "registerProcessObserver()");
7120        synchronized (this) {
7121            mProcessObservers.register(observer);
7122        }
7123    }
7124
7125    public void unregisterProcessObserver(IProcessObserver observer) {
7126        synchronized (this) {
7127            mProcessObservers.unregister(observer);
7128        }
7129    }
7130
7131    public void setImmersive(IBinder token, boolean immersive) {
7132        synchronized(this) {
7133            ActivityRecord r = mMainStack.isInStackLocked(token);
7134            if (r == null) {
7135                throw new IllegalArgumentException();
7136            }
7137            r.immersive = immersive;
7138        }
7139    }
7140
7141    public boolean isImmersive(IBinder token) {
7142        synchronized (this) {
7143            ActivityRecord r = mMainStack.isInStackLocked(token);
7144            if (r == null) {
7145                throw new IllegalArgumentException();
7146            }
7147            return r.immersive;
7148        }
7149    }
7150
7151    public boolean isTopActivityImmersive() {
7152        enforceNotIsolatedCaller("startActivity");
7153        synchronized (this) {
7154            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7155            return (r != null) ? r.immersive : false;
7156        }
7157    }
7158
7159    public final void enterSafeMode() {
7160        synchronized(this) {
7161            // It only makes sense to do this before the system is ready
7162            // and started launching other packages.
7163            if (!mSystemReady) {
7164                try {
7165                    AppGlobals.getPackageManager().enterSafeMode();
7166                } catch (RemoteException e) {
7167                }
7168            }
7169        }
7170    }
7171
7172    public final void showSafeModeOverlay() {
7173        View v = LayoutInflater.from(mContext).inflate(
7174                com.android.internal.R.layout.safe_mode, null);
7175        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7176        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7177        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7178        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7179        lp.gravity = Gravity.BOTTOM | Gravity.START;
7180        lp.format = v.getBackground().getOpacity();
7181        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7182                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7183        ((WindowManager)mContext.getSystemService(
7184                Context.WINDOW_SERVICE)).addView(v, lp);
7185    }
7186
7187    public void noteWakeupAlarm(IIntentSender sender) {
7188        if (!(sender instanceof PendingIntentRecord)) {
7189            return;
7190        }
7191        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7192        synchronized (stats) {
7193            if (mBatteryStatsService.isOnBattery()) {
7194                mBatteryStatsService.enforceCallingPermission();
7195                PendingIntentRecord rec = (PendingIntentRecord)sender;
7196                int MY_UID = Binder.getCallingUid();
7197                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7198                BatteryStatsImpl.Uid.Pkg pkg =
7199                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7200                pkg.incWakeupsLocked();
7201            }
7202        }
7203    }
7204
7205    public boolean killPids(int[] pids, String pReason, boolean secure) {
7206        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7207            throw new SecurityException("killPids only available to the system");
7208        }
7209        String reason = (pReason == null) ? "Unknown" : pReason;
7210        // XXX Note: don't acquire main activity lock here, because the window
7211        // manager calls in with its locks held.
7212
7213        boolean killed = false;
7214        synchronized (mPidsSelfLocked) {
7215            int[] types = new int[pids.length];
7216            int worstType = 0;
7217            for (int i=0; i<pids.length; i++) {
7218                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7219                if (proc != null) {
7220                    int type = proc.setAdj;
7221                    types[i] = type;
7222                    if (type > worstType) {
7223                        worstType = type;
7224                    }
7225                }
7226            }
7227
7228            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7229            // then constrain it so we will kill all hidden procs.
7230            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7231                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7232                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7233            }
7234
7235            // If this is not a secure call, don't let it kill processes that
7236            // are important.
7237            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7238                worstType = ProcessList.SERVICE_ADJ;
7239            }
7240
7241            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7242            for (int i=0; i<pids.length; i++) {
7243                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7244                if (proc == null) {
7245                    continue;
7246                }
7247                int adj = proc.setAdj;
7248                if (adj >= worstType && !proc.killedBackground) {
7249                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7250                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7251                            proc.processName, adj, reason);
7252                    killed = true;
7253                    proc.killedBackground = true;
7254                    Process.killProcessQuiet(pids[i]);
7255                }
7256            }
7257        }
7258        return killed;
7259    }
7260
7261    @Override
7262    public boolean killProcessesBelowForeground(String reason) {
7263        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7264            throw new SecurityException("killProcessesBelowForeground() only available to system");
7265        }
7266
7267        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7268    }
7269
7270    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7271        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7272            throw new SecurityException("killProcessesBelowAdj() only available to system");
7273        }
7274
7275        boolean killed = false;
7276        synchronized (mPidsSelfLocked) {
7277            final int size = mPidsSelfLocked.size();
7278            for (int i = 0; i < size; i++) {
7279                final int pid = mPidsSelfLocked.keyAt(i);
7280                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7281                if (proc == null) continue;
7282
7283                final int adj = proc.setAdj;
7284                if (adj > belowAdj && !proc.killedBackground) {
7285                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7286                    EventLog.writeEvent(
7287                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7288                    killed = true;
7289                    proc.killedBackground = true;
7290                    Process.killProcessQuiet(pid);
7291                }
7292            }
7293        }
7294        return killed;
7295    }
7296
7297    public final void startRunning(String pkg, String cls, String action,
7298            String data) {
7299        synchronized(this) {
7300            if (mStartRunning) {
7301                return;
7302            }
7303            mStartRunning = true;
7304            mTopComponent = pkg != null && cls != null
7305                    ? new ComponentName(pkg, cls) : null;
7306            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7307            mTopData = data;
7308            if (!mSystemReady) {
7309                return;
7310            }
7311        }
7312
7313        systemReady(null);
7314    }
7315
7316    private void retrieveSettings() {
7317        final ContentResolver resolver = mContext.getContentResolver();
7318        String debugApp = Settings.System.getString(
7319            resolver, Settings.System.DEBUG_APP);
7320        boolean waitForDebugger = Settings.System.getInt(
7321            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7322        boolean alwaysFinishActivities = Settings.System.getInt(
7323            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7324
7325        Configuration configuration = new Configuration();
7326        Settings.System.getConfiguration(resolver, configuration);
7327
7328        synchronized (this) {
7329            mDebugApp = mOrigDebugApp = debugApp;
7330            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7331            mAlwaysFinishActivities = alwaysFinishActivities;
7332            // This happens before any activities are started, so we can
7333            // change mConfiguration in-place.
7334            updateConfigurationLocked(configuration, null, false, true);
7335            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7336        }
7337    }
7338
7339    public boolean testIsSystemReady() {
7340        // no need to synchronize(this) just to read & return the value
7341        return mSystemReady;
7342    }
7343
7344    private static File getCalledPreBootReceiversFile() {
7345        File dataDir = Environment.getDataDirectory();
7346        File systemDir = new File(dataDir, "system");
7347        File fname = new File(systemDir, "called_pre_boots.dat");
7348        return fname;
7349    }
7350
7351    static final int LAST_DONE_VERSION = 10000;
7352
7353    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7354        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7355        File file = getCalledPreBootReceiversFile();
7356        FileInputStream fis = null;
7357        try {
7358            fis = new FileInputStream(file);
7359            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7360            int fvers = dis.readInt();
7361            if (fvers == LAST_DONE_VERSION) {
7362                String vers = dis.readUTF();
7363                String codename = dis.readUTF();
7364                String build = dis.readUTF();
7365                if (android.os.Build.VERSION.RELEASE.equals(vers)
7366                        && android.os.Build.VERSION.CODENAME.equals(codename)
7367                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7368                    int num = dis.readInt();
7369                    while (num > 0) {
7370                        num--;
7371                        String pkg = dis.readUTF();
7372                        String cls = dis.readUTF();
7373                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7374                    }
7375                }
7376            }
7377        } catch (FileNotFoundException e) {
7378        } catch (IOException e) {
7379            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7380        } finally {
7381            if (fis != null) {
7382                try {
7383                    fis.close();
7384                } catch (IOException e) {
7385                }
7386            }
7387        }
7388        return lastDoneReceivers;
7389    }
7390
7391    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7392        File file = getCalledPreBootReceiversFile();
7393        FileOutputStream fos = null;
7394        DataOutputStream dos = null;
7395        try {
7396            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7397            fos = new FileOutputStream(file);
7398            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7399            dos.writeInt(LAST_DONE_VERSION);
7400            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7401            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7402            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7403            dos.writeInt(list.size());
7404            for (int i=0; i<list.size(); i++) {
7405                dos.writeUTF(list.get(i).getPackageName());
7406                dos.writeUTF(list.get(i).getClassName());
7407            }
7408        } catch (IOException e) {
7409            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7410            file.delete();
7411        } finally {
7412            FileUtils.sync(fos);
7413            if (dos != null) {
7414                try {
7415                    dos.close();
7416                } catch (IOException e) {
7417                    // TODO Auto-generated catch block
7418                    e.printStackTrace();
7419                }
7420            }
7421        }
7422    }
7423
7424    public void systemReady(final Runnable goingCallback) {
7425        synchronized(this) {
7426            if (mSystemReady) {
7427                if (goingCallback != null) goingCallback.run();
7428                return;
7429            }
7430
7431            // Check to see if there are any update receivers to run.
7432            if (!mDidUpdate) {
7433                if (mWaitingUpdate) {
7434                    return;
7435                }
7436                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7437                List<ResolveInfo> ris = null;
7438                try {
7439                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7440                            intent, null, 0, 0);
7441                } catch (RemoteException e) {
7442                }
7443                if (ris != null) {
7444                    for (int i=ris.size()-1; i>=0; i--) {
7445                        if ((ris.get(i).activityInfo.applicationInfo.flags
7446                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7447                            ris.remove(i);
7448                        }
7449                    }
7450                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7451
7452                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7453
7454                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7455                    for (int i=0; i<ris.size(); i++) {
7456                        ActivityInfo ai = ris.get(i).activityInfo;
7457                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7458                        if (lastDoneReceivers.contains(comp)) {
7459                            ris.remove(i);
7460                            i--;
7461                        }
7462                    }
7463
7464                    for (int i=0; i<ris.size(); i++) {
7465                        ActivityInfo ai = ris.get(i).activityInfo;
7466                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7467                        doneReceivers.add(comp);
7468                        intent.setComponent(comp);
7469                        IIntentReceiver finisher = null;
7470                        if (i == ris.size()-1) {
7471                            finisher = new IIntentReceiver.Stub() {
7472                                public void performReceive(Intent intent, int resultCode,
7473                                        String data, Bundle extras, boolean ordered,
7474                                        boolean sticky) {
7475                                    // The raw IIntentReceiver interface is called
7476                                    // with the AM lock held, so redispatch to
7477                                    // execute our code without the lock.
7478                                    mHandler.post(new Runnable() {
7479                                        public void run() {
7480                                            synchronized (ActivityManagerService.this) {
7481                                                mDidUpdate = true;
7482                                            }
7483                                            writeLastDonePreBootReceivers(doneReceivers);
7484                                            showBootMessage(mContext.getText(
7485                                                    R.string.android_upgrading_complete),
7486                                                    false);
7487                                            systemReady(goingCallback);
7488                                        }
7489                                    });
7490                                }
7491                            };
7492                        }
7493                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7494                        /* TODO: Send this to all users */
7495                        broadcastIntentLocked(null, null, intent, null, finisher,
7496                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7497                                0 /* UserId zero */);
7498                        if (finisher != null) {
7499                            mWaitingUpdate = true;
7500                        }
7501                    }
7502                }
7503                if (mWaitingUpdate) {
7504                    return;
7505                }
7506                mDidUpdate = true;
7507            }
7508
7509            mSystemReady = true;
7510            if (!mStartRunning) {
7511                return;
7512            }
7513        }
7514
7515        ArrayList<ProcessRecord> procsToKill = null;
7516        synchronized(mPidsSelfLocked) {
7517            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7518                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7519                if (!isAllowedWhileBooting(proc.info)){
7520                    if (procsToKill == null) {
7521                        procsToKill = new ArrayList<ProcessRecord>();
7522                    }
7523                    procsToKill.add(proc);
7524                }
7525            }
7526        }
7527
7528        synchronized(this) {
7529            if (procsToKill != null) {
7530                for (int i=procsToKill.size()-1; i>=0; i--) {
7531                    ProcessRecord proc = procsToKill.get(i);
7532                    Slog.i(TAG, "Removing system update proc: " + proc);
7533                    removeProcessLocked(proc, true, false, "system update done");
7534                }
7535            }
7536
7537            // Now that we have cleaned up any update processes, we
7538            // are ready to start launching real processes and know that
7539            // we won't trample on them any more.
7540            mProcessesReady = true;
7541        }
7542
7543        Slog.i(TAG, "System now ready");
7544        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7545            SystemClock.uptimeMillis());
7546
7547        synchronized(this) {
7548            // Make sure we have no pre-ready processes sitting around.
7549
7550            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7551                ResolveInfo ri = mContext.getPackageManager()
7552                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7553                                STOCK_PM_FLAGS);
7554                CharSequence errorMsg = null;
7555                if (ri != null) {
7556                    ActivityInfo ai = ri.activityInfo;
7557                    ApplicationInfo app = ai.applicationInfo;
7558                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7559                        mTopAction = Intent.ACTION_FACTORY_TEST;
7560                        mTopData = null;
7561                        mTopComponent = new ComponentName(app.packageName,
7562                                ai.name);
7563                    } else {
7564                        errorMsg = mContext.getResources().getText(
7565                                com.android.internal.R.string.factorytest_not_system);
7566                    }
7567                } else {
7568                    errorMsg = mContext.getResources().getText(
7569                            com.android.internal.R.string.factorytest_no_action);
7570                }
7571                if (errorMsg != null) {
7572                    mTopAction = null;
7573                    mTopData = null;
7574                    mTopComponent = null;
7575                    Message msg = Message.obtain();
7576                    msg.what = SHOW_FACTORY_ERROR_MSG;
7577                    msg.getData().putCharSequence("msg", errorMsg);
7578                    mHandler.sendMessage(msg);
7579                }
7580            }
7581        }
7582
7583        retrieveSettings();
7584
7585        if (goingCallback != null) goingCallback.run();
7586
7587        synchronized (this) {
7588            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7589                try {
7590                    List apps = AppGlobals.getPackageManager().
7591                        getPersistentApplications(STOCK_PM_FLAGS);
7592                    if (apps != null) {
7593                        int N = apps.size();
7594                        int i;
7595                        for (i=0; i<N; i++) {
7596                            ApplicationInfo info
7597                                = (ApplicationInfo)apps.get(i);
7598                            if (info != null &&
7599                                    !info.packageName.equals("android")) {
7600                                addAppLocked(info, false);
7601                            }
7602                        }
7603                    }
7604                } catch (RemoteException ex) {
7605                    // pm is in same process, this will never happen.
7606                }
7607            }
7608
7609            // Start up initial activity.
7610            mBooting = true;
7611
7612            try {
7613                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7614                    Message msg = Message.obtain();
7615                    msg.what = SHOW_UID_ERROR_MSG;
7616                    mHandler.sendMessage(msg);
7617                }
7618            } catch (RemoteException e) {
7619            }
7620
7621            mMainStack.resumeTopActivityLocked(null);
7622        }
7623    }
7624
7625    private boolean makeAppCrashingLocked(ProcessRecord app,
7626            String shortMsg, String longMsg, String stackTrace) {
7627        app.crashing = true;
7628        app.crashingReport = generateProcessError(app,
7629                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7630        startAppProblemLocked(app);
7631        app.stopFreezingAllLocked();
7632        return handleAppCrashLocked(app);
7633    }
7634
7635    private void makeAppNotRespondingLocked(ProcessRecord app,
7636            String activity, String shortMsg, String longMsg) {
7637        app.notResponding = true;
7638        app.notRespondingReport = generateProcessError(app,
7639                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7640                activity, shortMsg, longMsg, null);
7641        startAppProblemLocked(app);
7642        app.stopFreezingAllLocked();
7643    }
7644
7645    /**
7646     * Generate a process error record, suitable for attachment to a ProcessRecord.
7647     *
7648     * @param app The ProcessRecord in which the error occurred.
7649     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7650     *                      ActivityManager.AppErrorStateInfo
7651     * @param activity The activity associated with the crash, if known.
7652     * @param shortMsg Short message describing the crash.
7653     * @param longMsg Long message describing the crash.
7654     * @param stackTrace Full crash stack trace, may be null.
7655     *
7656     * @return Returns a fully-formed AppErrorStateInfo record.
7657     */
7658    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7659            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7660        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7661
7662        report.condition = condition;
7663        report.processName = app.processName;
7664        report.pid = app.pid;
7665        report.uid = app.info.uid;
7666        report.tag = activity;
7667        report.shortMsg = shortMsg;
7668        report.longMsg = longMsg;
7669        report.stackTrace = stackTrace;
7670
7671        return report;
7672    }
7673
7674    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7675        synchronized (this) {
7676            app.crashing = false;
7677            app.crashingReport = null;
7678            app.notResponding = false;
7679            app.notRespondingReport = null;
7680            if (app.anrDialog == fromDialog) {
7681                app.anrDialog = null;
7682            }
7683            if (app.waitDialog == fromDialog) {
7684                app.waitDialog = null;
7685            }
7686            if (app.pid > 0 && app.pid != MY_PID) {
7687                handleAppCrashLocked(app);
7688                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7689                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7690                        app.processName, app.setAdj, "user's request after error");
7691                Process.killProcessQuiet(app.pid);
7692            }
7693        }
7694    }
7695
7696    private boolean handleAppCrashLocked(ProcessRecord app) {
7697        if (mHeadless) {
7698            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7699            return false;
7700        }
7701        long now = SystemClock.uptimeMillis();
7702
7703        Long crashTime;
7704        if (!app.isolated) {
7705            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7706        } else {
7707            crashTime = null;
7708        }
7709        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7710            // This process loses!
7711            Slog.w(TAG, "Process " + app.info.processName
7712                    + " has crashed too many times: killing!");
7713            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7714                    app.info.processName, app.uid);
7715            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7716                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7717                if (r.app == app) {
7718                    Slog.w(TAG, "  Force finishing activity "
7719                        + r.intent.getComponent().flattenToShortString());
7720                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7721                }
7722            }
7723            if (!app.persistent) {
7724                // We don't want to start this process again until the user
7725                // explicitly does so...  but for persistent process, we really
7726                // need to keep it running.  If a persistent process is actually
7727                // repeatedly crashing, then badness for everyone.
7728                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7729                        app.info.processName);
7730                if (!app.isolated) {
7731                    // XXX We don't have a way to mark isolated processes
7732                    // as bad, since they don't have a peristent identity.
7733                    mBadProcesses.put(app.info.processName, app.uid, now);
7734                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7735                }
7736                app.bad = true;
7737                app.removed = true;
7738                // Don't let services in this process be restarted and potentially
7739                // annoy the user repeatedly.  Unless it is persistent, since those
7740                // processes run critical code.
7741                removeProcessLocked(app, false, false, "crash");
7742                mMainStack.resumeTopActivityLocked(null);
7743                return false;
7744            }
7745            mMainStack.resumeTopActivityLocked(null);
7746        } else {
7747            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7748            if (r != null && r.app == app) {
7749                // If the top running activity is from this crashing
7750                // process, then terminate it to avoid getting in a loop.
7751                Slog.w(TAG, "  Force finishing activity "
7752                        + r.intent.getComponent().flattenToShortString());
7753                int index = mMainStack.indexOfActivityLocked(r);
7754                r.stack.finishActivityLocked(r, index,
7755                        Activity.RESULT_CANCELED, null, "crashed");
7756                // Also terminate any activities below it that aren't yet
7757                // stopped, to avoid a situation where one will get
7758                // re-start our crashing activity once it gets resumed again.
7759                index--;
7760                if (index >= 0) {
7761                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7762                    if (r.state == ActivityState.RESUMED
7763                            || r.state == ActivityState.PAUSING
7764                            || r.state == ActivityState.PAUSED) {
7765                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7766                            Slog.w(TAG, "  Force finishing activity "
7767                                    + r.intent.getComponent().flattenToShortString());
7768                            r.stack.finishActivityLocked(r, index,
7769                                    Activity.RESULT_CANCELED, null, "crashed");
7770                        }
7771                    }
7772                }
7773            }
7774        }
7775
7776        // Bump up the crash count of any services currently running in the proc.
7777        if (app.services.size() != 0) {
7778            // Any services running in the application need to be placed
7779            // back in the pending list.
7780            Iterator<ServiceRecord> it = app.services.iterator();
7781            while (it.hasNext()) {
7782                ServiceRecord sr = it.next();
7783                sr.crashCount++;
7784            }
7785        }
7786
7787        // If the crashing process is what we consider to be the "home process" and it has been
7788        // replaced by a third-party app, clear the package preferred activities from packages
7789        // with a home activity running in the process to prevent a repeatedly crashing app
7790        // from blocking the user to manually clear the list.
7791        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7792                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7793            Iterator it = mHomeProcess.activities.iterator();
7794            while (it.hasNext()) {
7795                ActivityRecord r = (ActivityRecord)it.next();
7796                if (r.isHomeActivity) {
7797                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7798                    try {
7799                        ActivityThread.getPackageManager()
7800                                .clearPackagePreferredActivities(r.packageName);
7801                    } catch (RemoteException c) {
7802                        // pm is in same process, this will never happen.
7803                    }
7804                }
7805            }
7806        }
7807
7808        if (!app.isolated) {
7809            // XXX Can't keep track of crash times for isolated processes,
7810            // because they don't have a perisistent identity.
7811            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7812        }
7813
7814        return true;
7815    }
7816
7817    void startAppProblemLocked(ProcessRecord app) {
7818        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7819                mContext, app.info.packageName, app.info.flags);
7820        skipCurrentReceiverLocked(app);
7821    }
7822
7823    void skipCurrentReceiverLocked(ProcessRecord app) {
7824        for (BroadcastQueue queue : mBroadcastQueues) {
7825            queue.skipCurrentReceiverLocked(app);
7826        }
7827    }
7828
7829    /**
7830     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7831     * The application process will exit immediately after this call returns.
7832     * @param app object of the crashing app, null for the system server
7833     * @param crashInfo describing the exception
7834     */
7835    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7836        ProcessRecord r = findAppProcess(app, "Crash");
7837        final String processName = app == null ? "system_server"
7838                : (r == null ? "unknown" : r.processName);
7839
7840        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7841                processName,
7842                r == null ? -1 : r.info.flags,
7843                crashInfo.exceptionClassName,
7844                crashInfo.exceptionMessage,
7845                crashInfo.throwFileName,
7846                crashInfo.throwLineNumber);
7847
7848        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7849
7850        crashApplication(r, crashInfo);
7851    }
7852
7853    public void handleApplicationStrictModeViolation(
7854            IBinder app,
7855            int violationMask,
7856            StrictMode.ViolationInfo info) {
7857        ProcessRecord r = findAppProcess(app, "StrictMode");
7858        if (r == null) {
7859            return;
7860        }
7861
7862        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7863            Integer stackFingerprint = info.hashCode();
7864            boolean logIt = true;
7865            synchronized (mAlreadyLoggedViolatedStacks) {
7866                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7867                    logIt = false;
7868                    // TODO: sub-sample into EventLog for these, with
7869                    // the info.durationMillis?  Then we'd get
7870                    // the relative pain numbers, without logging all
7871                    // the stack traces repeatedly.  We'd want to do
7872                    // likewise in the client code, which also does
7873                    // dup suppression, before the Binder call.
7874                } else {
7875                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7876                        mAlreadyLoggedViolatedStacks.clear();
7877                    }
7878                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7879                }
7880            }
7881            if (logIt) {
7882                logStrictModeViolationToDropBox(r, info);
7883            }
7884        }
7885
7886        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7887            AppErrorResult result = new AppErrorResult();
7888            synchronized (this) {
7889                final long origId = Binder.clearCallingIdentity();
7890
7891                Message msg = Message.obtain();
7892                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7893                HashMap<String, Object> data = new HashMap<String, Object>();
7894                data.put("result", result);
7895                data.put("app", r);
7896                data.put("violationMask", violationMask);
7897                data.put("info", info);
7898                msg.obj = data;
7899                mHandler.sendMessage(msg);
7900
7901                Binder.restoreCallingIdentity(origId);
7902            }
7903            int res = result.get();
7904            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7905        }
7906    }
7907
7908    // Depending on the policy in effect, there could be a bunch of
7909    // these in quick succession so we try to batch these together to
7910    // minimize disk writes, number of dropbox entries, and maximize
7911    // compression, by having more fewer, larger records.
7912    private void logStrictModeViolationToDropBox(
7913            ProcessRecord process,
7914            StrictMode.ViolationInfo info) {
7915        if (info == null) {
7916            return;
7917        }
7918        final boolean isSystemApp = process == null ||
7919                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7920                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7921        final String processName = process == null ? "unknown" : process.processName;
7922        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7923        final DropBoxManager dbox = (DropBoxManager)
7924                mContext.getSystemService(Context.DROPBOX_SERVICE);
7925
7926        // Exit early if the dropbox isn't configured to accept this report type.
7927        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7928
7929        boolean bufferWasEmpty;
7930        boolean needsFlush;
7931        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7932        synchronized (sb) {
7933            bufferWasEmpty = sb.length() == 0;
7934            appendDropBoxProcessHeaders(process, processName, sb);
7935            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7936            sb.append("System-App: ").append(isSystemApp).append("\n");
7937            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7938            if (info.violationNumThisLoop != 0) {
7939                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7940            }
7941            if (info.numAnimationsRunning != 0) {
7942                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7943            }
7944            if (info.broadcastIntentAction != null) {
7945                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7946            }
7947            if (info.durationMillis != -1) {
7948                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7949            }
7950            if (info.numInstances != -1) {
7951                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7952            }
7953            if (info.tags != null) {
7954                for (String tag : info.tags) {
7955                    sb.append("Span-Tag: ").append(tag).append("\n");
7956                }
7957            }
7958            sb.append("\n");
7959            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7960                sb.append(info.crashInfo.stackTrace);
7961            }
7962            sb.append("\n");
7963
7964            // Only buffer up to ~64k.  Various logging bits truncate
7965            // things at 128k.
7966            needsFlush = (sb.length() > 64 * 1024);
7967        }
7968
7969        // Flush immediately if the buffer's grown too large, or this
7970        // is a non-system app.  Non-system apps are isolated with a
7971        // different tag & policy and not batched.
7972        //
7973        // Batching is useful during internal testing with
7974        // StrictMode settings turned up high.  Without batching,
7975        // thousands of separate files could be created on boot.
7976        if (!isSystemApp || needsFlush) {
7977            new Thread("Error dump: " + dropboxTag) {
7978                @Override
7979                public void run() {
7980                    String report;
7981                    synchronized (sb) {
7982                        report = sb.toString();
7983                        sb.delete(0, sb.length());
7984                        sb.trimToSize();
7985                    }
7986                    if (report.length() != 0) {
7987                        dbox.addText(dropboxTag, report);
7988                    }
7989                }
7990            }.start();
7991            return;
7992        }
7993
7994        // System app batching:
7995        if (!bufferWasEmpty) {
7996            // An existing dropbox-writing thread is outstanding, so
7997            // we don't need to start it up.  The existing thread will
7998            // catch the buffer appends we just did.
7999            return;
8000        }
8001
8002        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8003        // (After this point, we shouldn't access AMS internal data structures.)
8004        new Thread("Error dump: " + dropboxTag) {
8005            @Override
8006            public void run() {
8007                // 5 second sleep to let stacks arrive and be batched together
8008                try {
8009                    Thread.sleep(5000);  // 5 seconds
8010                } catch (InterruptedException e) {}
8011
8012                String errorReport;
8013                synchronized (mStrictModeBuffer) {
8014                    errorReport = mStrictModeBuffer.toString();
8015                    if (errorReport.length() == 0) {
8016                        return;
8017                    }
8018                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8019                    mStrictModeBuffer.trimToSize();
8020                }
8021                dbox.addText(dropboxTag, errorReport);
8022            }
8023        }.start();
8024    }
8025
8026    /**
8027     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8028     * @param app object of the crashing app, null for the system server
8029     * @param tag reported by the caller
8030     * @param crashInfo describing the context of the error
8031     * @return true if the process should exit immediately (WTF is fatal)
8032     */
8033    public boolean handleApplicationWtf(IBinder app, String tag,
8034            ApplicationErrorReport.CrashInfo crashInfo) {
8035        ProcessRecord r = findAppProcess(app, "WTF");
8036        final String processName = app == null ? "system_server"
8037                : (r == null ? "unknown" : r.processName);
8038
8039        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8040                processName,
8041                r == null ? -1 : r.info.flags,
8042                tag, crashInfo.exceptionMessage);
8043
8044        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8045
8046        if (r != null && r.pid != Process.myPid() &&
8047                Settings.Secure.getInt(mContext.getContentResolver(),
8048                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8049            crashApplication(r, crashInfo);
8050            return true;
8051        } else {
8052            return false;
8053        }
8054    }
8055
8056    /**
8057     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8058     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8059     */
8060    private ProcessRecord findAppProcess(IBinder app, String reason) {
8061        if (app == null) {
8062            return null;
8063        }
8064
8065        synchronized (this) {
8066            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8067                final int NA = apps.size();
8068                for (int ia=0; ia<NA; ia++) {
8069                    ProcessRecord p = apps.valueAt(ia);
8070                    if (p.thread != null && p.thread.asBinder() == app) {
8071                        return p;
8072                    }
8073                }
8074            }
8075
8076            Slog.w(TAG, "Can't find mystery application for " + reason
8077                    + " from pid=" + Binder.getCallingPid()
8078                    + " uid=" + Binder.getCallingUid() + ": " + app);
8079            return null;
8080        }
8081    }
8082
8083    /**
8084     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8085     * to append various headers to the dropbox log text.
8086     */
8087    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8088            StringBuilder sb) {
8089        // Watchdog thread ends up invoking this function (with
8090        // a null ProcessRecord) to add the stack file to dropbox.
8091        // Do not acquire a lock on this (am) in such cases, as it
8092        // could cause a potential deadlock, if and when watchdog
8093        // is invoked due to unavailability of lock on am and it
8094        // would prevent watchdog from killing system_server.
8095        if (process == null) {
8096            sb.append("Process: ").append(processName).append("\n");
8097            return;
8098        }
8099        // Note: ProcessRecord 'process' is guarded by the service
8100        // instance.  (notably process.pkgList, which could otherwise change
8101        // concurrently during execution of this method)
8102        synchronized (this) {
8103            sb.append("Process: ").append(processName).append("\n");
8104            int flags = process.info.flags;
8105            IPackageManager pm = AppGlobals.getPackageManager();
8106            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8107            for (String pkg : process.pkgList) {
8108                sb.append("Package: ").append(pkg);
8109                try {
8110                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8111                    if (pi != null) {
8112                        sb.append(" v").append(pi.versionCode);
8113                        if (pi.versionName != null) {
8114                            sb.append(" (").append(pi.versionName).append(")");
8115                        }
8116                    }
8117                } catch (RemoteException e) {
8118                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8119                }
8120                sb.append("\n");
8121            }
8122        }
8123    }
8124
8125    private static String processClass(ProcessRecord process) {
8126        if (process == null || process.pid == MY_PID) {
8127            return "system_server";
8128        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8129            return "system_app";
8130        } else {
8131            return "data_app";
8132        }
8133    }
8134
8135    /**
8136     * Write a description of an error (crash, WTF, ANR) to the drop box.
8137     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8138     * @param process which caused the error, null means the system server
8139     * @param activity which triggered the error, null if unknown
8140     * @param parent activity related to the error, null if unknown
8141     * @param subject line related to the error, null if absent
8142     * @param report in long form describing the error, null if absent
8143     * @param logFile to include in the report, null if none
8144     * @param crashInfo giving an application stack trace, null if absent
8145     */
8146    public void addErrorToDropBox(String eventType,
8147            ProcessRecord process, String processName, ActivityRecord activity,
8148            ActivityRecord parent, String subject,
8149            final String report, final File logFile,
8150            final ApplicationErrorReport.CrashInfo crashInfo) {
8151        // NOTE -- this must never acquire the ActivityManagerService lock,
8152        // otherwise the watchdog may be prevented from resetting the system.
8153
8154        final String dropboxTag = processClass(process) + "_" + eventType;
8155        final DropBoxManager dbox = (DropBoxManager)
8156                mContext.getSystemService(Context.DROPBOX_SERVICE);
8157
8158        // Exit early if the dropbox isn't configured to accept this report type.
8159        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8160
8161        final StringBuilder sb = new StringBuilder(1024);
8162        appendDropBoxProcessHeaders(process, processName, sb);
8163        if (activity != null) {
8164            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8165        }
8166        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8167            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8168        }
8169        if (parent != null && parent != activity) {
8170            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8171        }
8172        if (subject != null) {
8173            sb.append("Subject: ").append(subject).append("\n");
8174        }
8175        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8176        if (Debug.isDebuggerConnected()) {
8177            sb.append("Debugger: Connected\n");
8178        }
8179        sb.append("\n");
8180
8181        // Do the rest in a worker thread to avoid blocking the caller on I/O
8182        // (After this point, we shouldn't access AMS internal data structures.)
8183        Thread worker = new Thread("Error dump: " + dropboxTag) {
8184            @Override
8185            public void run() {
8186                if (report != null) {
8187                    sb.append(report);
8188                }
8189                if (logFile != null) {
8190                    try {
8191                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8192                    } catch (IOException e) {
8193                        Slog.e(TAG, "Error reading " + logFile, e);
8194                    }
8195                }
8196                if (crashInfo != null && crashInfo.stackTrace != null) {
8197                    sb.append(crashInfo.stackTrace);
8198                }
8199
8200                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8201                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8202                if (lines > 0) {
8203                    sb.append("\n");
8204
8205                    // Merge several logcat streams, and take the last N lines
8206                    InputStreamReader input = null;
8207                    try {
8208                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8209                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8210                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8211
8212                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8213                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8214                        input = new InputStreamReader(logcat.getInputStream());
8215
8216                        int num;
8217                        char[] buf = new char[8192];
8218                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8219                    } catch (IOException e) {
8220                        Slog.e(TAG, "Error running logcat", e);
8221                    } finally {
8222                        if (input != null) try { input.close(); } catch (IOException e) {}
8223                    }
8224                }
8225
8226                dbox.addText(dropboxTag, sb.toString());
8227            }
8228        };
8229
8230        if (process == null) {
8231            // If process is null, we are being called from some internal code
8232            // and may be about to die -- run this synchronously.
8233            worker.run();
8234        } else {
8235            worker.start();
8236        }
8237    }
8238
8239    /**
8240     * Bring up the "unexpected error" dialog box for a crashing app.
8241     * Deal with edge cases (intercepts from instrumented applications,
8242     * ActivityController, error intent receivers, that sort of thing).
8243     * @param r the application crashing
8244     * @param crashInfo describing the failure
8245     */
8246    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8247        long timeMillis = System.currentTimeMillis();
8248        String shortMsg = crashInfo.exceptionClassName;
8249        String longMsg = crashInfo.exceptionMessage;
8250        String stackTrace = crashInfo.stackTrace;
8251        if (shortMsg != null && longMsg != null) {
8252            longMsg = shortMsg + ": " + longMsg;
8253        } else if (shortMsg != null) {
8254            longMsg = shortMsg;
8255        }
8256
8257        AppErrorResult result = new AppErrorResult();
8258        synchronized (this) {
8259            if (mController != null) {
8260                try {
8261                    String name = r != null ? r.processName : null;
8262                    int pid = r != null ? r.pid : Binder.getCallingPid();
8263                    if (!mController.appCrashed(name, pid,
8264                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8265                        Slog.w(TAG, "Force-killing crashed app " + name
8266                                + " at watcher's request");
8267                        Process.killProcess(pid);
8268                        return;
8269                    }
8270                } catch (RemoteException e) {
8271                    mController = null;
8272                }
8273            }
8274
8275            final long origId = Binder.clearCallingIdentity();
8276
8277            // If this process is running instrumentation, finish it.
8278            if (r != null && r.instrumentationClass != null) {
8279                Slog.w(TAG, "Error in app " + r.processName
8280                      + " running instrumentation " + r.instrumentationClass + ":");
8281                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8282                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8283                Bundle info = new Bundle();
8284                info.putString("shortMsg", shortMsg);
8285                info.putString("longMsg", longMsg);
8286                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8287                Binder.restoreCallingIdentity(origId);
8288                return;
8289            }
8290
8291            // If we can't identify the process or it's already exceeded its crash quota,
8292            // quit right away without showing a crash dialog.
8293            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8294                Binder.restoreCallingIdentity(origId);
8295                return;
8296            }
8297
8298            Message msg = Message.obtain();
8299            msg.what = SHOW_ERROR_MSG;
8300            HashMap data = new HashMap();
8301            data.put("result", result);
8302            data.put("app", r);
8303            msg.obj = data;
8304            mHandler.sendMessage(msg);
8305
8306            Binder.restoreCallingIdentity(origId);
8307        }
8308
8309        int res = result.get();
8310
8311        Intent appErrorIntent = null;
8312        synchronized (this) {
8313            if (r != null && !r.isolated) {
8314                // XXX Can't keep track of crash time for isolated processes,
8315                // since they don't have a persistent identity.
8316                mProcessCrashTimes.put(r.info.processName, r.uid,
8317                        SystemClock.uptimeMillis());
8318            }
8319            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8320                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8321            }
8322        }
8323
8324        if (appErrorIntent != null) {
8325            try {
8326                mContext.startActivity(appErrorIntent);
8327            } catch (ActivityNotFoundException e) {
8328                Slog.w(TAG, "bug report receiver dissappeared", e);
8329            }
8330        }
8331    }
8332
8333    Intent createAppErrorIntentLocked(ProcessRecord r,
8334            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8335        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8336        if (report == null) {
8337            return null;
8338        }
8339        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8340        result.setComponent(r.errorReportReceiver);
8341        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8342        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8343        return result;
8344    }
8345
8346    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8347            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8348        if (r.errorReportReceiver == null) {
8349            return null;
8350        }
8351
8352        if (!r.crashing && !r.notResponding) {
8353            return null;
8354        }
8355
8356        ApplicationErrorReport report = new ApplicationErrorReport();
8357        report.packageName = r.info.packageName;
8358        report.installerPackageName = r.errorReportReceiver.getPackageName();
8359        report.processName = r.processName;
8360        report.time = timeMillis;
8361        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8362
8363        if (r.crashing) {
8364            report.type = ApplicationErrorReport.TYPE_CRASH;
8365            report.crashInfo = crashInfo;
8366        } else if (r.notResponding) {
8367            report.type = ApplicationErrorReport.TYPE_ANR;
8368            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8369
8370            report.anrInfo.activity = r.notRespondingReport.tag;
8371            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8372            report.anrInfo.info = r.notRespondingReport.longMsg;
8373        }
8374
8375        return report;
8376    }
8377
8378    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8379        enforceNotIsolatedCaller("getProcessesInErrorState");
8380        // assume our apps are happy - lazy create the list
8381        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8382
8383        synchronized (this) {
8384
8385            // iterate across all processes
8386            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8387                ProcessRecord app = mLruProcesses.get(i);
8388                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8389                    // This one's in trouble, so we'll generate a report for it
8390                    // crashes are higher priority (in case there's a crash *and* an anr)
8391                    ActivityManager.ProcessErrorStateInfo report = null;
8392                    if (app.crashing) {
8393                        report = app.crashingReport;
8394                    } else if (app.notResponding) {
8395                        report = app.notRespondingReport;
8396                    }
8397
8398                    if (report != null) {
8399                        if (errList == null) {
8400                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8401                        }
8402                        errList.add(report);
8403                    } else {
8404                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8405                                " crashing = " + app.crashing +
8406                                " notResponding = " + app.notResponding);
8407                    }
8408                }
8409            }
8410        }
8411
8412        return errList;
8413    }
8414
8415    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8416        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8417            if (currApp != null) {
8418                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8419            }
8420            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8421        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8422            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8423        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8424            if (currApp != null) {
8425                currApp.lru = 0;
8426            }
8427            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8428        } else if (adj >= ProcessList.SERVICE_ADJ) {
8429            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8430        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8431            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8432        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8433            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8434        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8435            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8436        } else {
8437            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8438        }
8439    }
8440
8441    private void fillInProcMemInfo(ProcessRecord app,
8442            ActivityManager.RunningAppProcessInfo outInfo) {
8443        outInfo.pid = app.pid;
8444        outInfo.uid = app.info.uid;
8445        if (mHeavyWeightProcess == app) {
8446            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8447        }
8448        if (app.persistent) {
8449            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8450        }
8451        outInfo.lastTrimLevel = app.trimMemoryLevel;
8452        int adj = app.curAdj;
8453        outInfo.importance = oomAdjToImportance(adj, outInfo);
8454        outInfo.importanceReasonCode = app.adjTypeCode;
8455    }
8456
8457    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8458        enforceNotIsolatedCaller("getRunningAppProcesses");
8459        // Lazy instantiation of list
8460        List<ActivityManager.RunningAppProcessInfo> runList = null;
8461        synchronized (this) {
8462            // Iterate across all processes
8463            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8464                ProcessRecord app = mLruProcesses.get(i);
8465                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8466                    // Generate process state info for running application
8467                    ActivityManager.RunningAppProcessInfo currApp =
8468                        new ActivityManager.RunningAppProcessInfo(app.processName,
8469                                app.pid, app.getPackageList());
8470                    fillInProcMemInfo(app, currApp);
8471                    if (app.adjSource instanceof ProcessRecord) {
8472                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8473                        currApp.importanceReasonImportance = oomAdjToImportance(
8474                                app.adjSourceOom, null);
8475                    } else if (app.adjSource instanceof ActivityRecord) {
8476                        ActivityRecord r = (ActivityRecord)app.adjSource;
8477                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8478                    }
8479                    if (app.adjTarget instanceof ComponentName) {
8480                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8481                    }
8482                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8483                    //        + " lru=" + currApp.lru);
8484                    if (runList == null) {
8485                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8486                    }
8487                    runList.add(currApp);
8488                }
8489            }
8490        }
8491        return runList;
8492    }
8493
8494    public List<ApplicationInfo> getRunningExternalApplications() {
8495        enforceNotIsolatedCaller("getRunningExternalApplications");
8496        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8497        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8498        if (runningApps != null && runningApps.size() > 0) {
8499            Set<String> extList = new HashSet<String>();
8500            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8501                if (app.pkgList != null) {
8502                    for (String pkg : app.pkgList) {
8503                        extList.add(pkg);
8504                    }
8505                }
8506            }
8507            IPackageManager pm = AppGlobals.getPackageManager();
8508            for (String pkg : extList) {
8509                try {
8510                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8511                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8512                        retList.add(info);
8513                    }
8514                } catch (RemoteException e) {
8515                }
8516            }
8517        }
8518        return retList;
8519    }
8520
8521    @Override
8522    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8523        enforceNotIsolatedCaller("getMyMemoryState");
8524        synchronized (this) {
8525            ProcessRecord proc;
8526            synchronized (mPidsSelfLocked) {
8527                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8528            }
8529            fillInProcMemInfo(proc, outInfo);
8530        }
8531    }
8532
8533    @Override
8534    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8535        if (checkCallingPermission(android.Manifest.permission.DUMP)
8536                != PackageManager.PERMISSION_GRANTED) {
8537            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8538                    + Binder.getCallingPid()
8539                    + ", uid=" + Binder.getCallingUid()
8540                    + " without permission "
8541                    + android.Manifest.permission.DUMP);
8542            return;
8543        }
8544
8545        boolean dumpAll = false;
8546        boolean dumpClient = false;
8547        String dumpPackage = null;
8548
8549        int opti = 0;
8550        while (opti < args.length) {
8551            String opt = args[opti];
8552            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8553                break;
8554            }
8555            opti++;
8556            if ("-a".equals(opt)) {
8557                dumpAll = true;
8558            } else if ("-c".equals(opt)) {
8559                dumpClient = true;
8560            } else if ("-h".equals(opt)) {
8561                pw.println("Activity manager dump options:");
8562                pw.println("  [-a] [-c] [-h] [cmd] ...");
8563                pw.println("  cmd may be one of:");
8564                pw.println("    a[ctivities]: activity stack state");
8565                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8566                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8567                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8568                pw.println("    o[om]: out of memory management");
8569                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8570                pw.println("    provider [COMP_SPEC]: provider client-side state");
8571                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8572                pw.println("    service [COMP_SPEC]: service client-side state");
8573                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8574                pw.println("    all: dump all activities");
8575                pw.println("    top: dump the top activity");
8576                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8577                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8578                pw.println("    a partial substring in a component name, a");
8579                pw.println("    hex object identifier.");
8580                pw.println("  -a: include all available server state.");
8581                pw.println("  -c: include client state.");
8582                return;
8583            } else {
8584                pw.println("Unknown argument: " + opt + "; use -h for help");
8585            }
8586        }
8587
8588        long origId = Binder.clearCallingIdentity();
8589        boolean more = false;
8590        // Is the caller requesting to dump a particular piece of data?
8591        if (opti < args.length) {
8592            String cmd = args[opti];
8593            opti++;
8594            if ("activities".equals(cmd) || "a".equals(cmd)) {
8595                synchronized (this) {
8596                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8597                }
8598            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8599                String[] newArgs;
8600                String name;
8601                if (opti >= args.length) {
8602                    name = null;
8603                    newArgs = EMPTY_STRING_ARRAY;
8604                } else {
8605                    name = args[opti];
8606                    opti++;
8607                    newArgs = new String[args.length - opti];
8608                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8609                            args.length - opti);
8610                }
8611                synchronized (this) {
8612                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8613                }
8614            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8615                String[] newArgs;
8616                String name;
8617                if (opti >= args.length) {
8618                    name = null;
8619                    newArgs = EMPTY_STRING_ARRAY;
8620                } else {
8621                    name = args[opti];
8622                    opti++;
8623                    newArgs = new String[args.length - opti];
8624                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8625                            args.length - opti);
8626                }
8627                synchronized (this) {
8628                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8629                }
8630            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8631                String[] newArgs;
8632                String name;
8633                if (opti >= args.length) {
8634                    name = null;
8635                    newArgs = EMPTY_STRING_ARRAY;
8636                } else {
8637                    name = args[opti];
8638                    opti++;
8639                    newArgs = new String[args.length - opti];
8640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8641                            args.length - opti);
8642                }
8643                synchronized (this) {
8644                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8645                }
8646            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8647                synchronized (this) {
8648                    dumpOomLocked(fd, pw, args, opti, true);
8649                }
8650            } else if ("provider".equals(cmd)) {
8651                String[] newArgs;
8652                String name;
8653                if (opti >= args.length) {
8654                    name = null;
8655                    newArgs = EMPTY_STRING_ARRAY;
8656                } else {
8657                    name = args[opti];
8658                    opti++;
8659                    newArgs = new String[args.length - opti];
8660                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8661                }
8662                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8663                    pw.println("No providers match: " + name);
8664                    pw.println("Use -h for help.");
8665                }
8666            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8667                synchronized (this) {
8668                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8669                }
8670            } else if ("service".equals(cmd)) {
8671                String[] newArgs;
8672                String name;
8673                if (opti >= args.length) {
8674                    name = null;
8675                    newArgs = EMPTY_STRING_ARRAY;
8676                } else {
8677                    name = args[opti];
8678                    opti++;
8679                    newArgs = new String[args.length - opti];
8680                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8681                            args.length - opti);
8682                }
8683                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8684                    pw.println("No services match: " + name);
8685                    pw.println("Use -h for help.");
8686                }
8687            } else if ("package".equals(cmd)) {
8688                String[] newArgs;
8689                if (opti >= args.length) {
8690                    pw.println("package: no package name specified");
8691                    pw.println("Use -h for help.");
8692                } else {
8693                    dumpPackage = args[opti];
8694                    opti++;
8695                    newArgs = new String[args.length - opti];
8696                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8697                            args.length - opti);
8698                    args = newArgs;
8699                    opti = 0;
8700                    more = true;
8701                }
8702            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8703                synchronized (this) {
8704                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8705                }
8706            } else {
8707                // Dumping a single activity?
8708                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8709                    pw.println("Bad activity command, or no activities match: " + cmd);
8710                    pw.println("Use -h for help.");
8711                }
8712            }
8713            if (!more) {
8714                Binder.restoreCallingIdentity(origId);
8715                return;
8716            }
8717        }
8718
8719        // No piece of data specified, dump everything.
8720        synchronized (this) {
8721            boolean needSep;
8722            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8723            if (needSep) {
8724                pw.println(" ");
8725            }
8726            if (dumpAll) {
8727                pw.println("-------------------------------------------------------------------------------");
8728            }
8729            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8730            if (needSep) {
8731                pw.println(" ");
8732            }
8733            if (dumpAll) {
8734                pw.println("-------------------------------------------------------------------------------");
8735            }
8736            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8737            if (needSep) {
8738                pw.println(" ");
8739            }
8740            if (dumpAll) {
8741                pw.println("-------------------------------------------------------------------------------");
8742            }
8743            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8744            if (needSep) {
8745                pw.println(" ");
8746            }
8747            if (dumpAll) {
8748                pw.println("-------------------------------------------------------------------------------");
8749            }
8750            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8751            if (needSep) {
8752                pw.println(" ");
8753            }
8754            if (dumpAll) {
8755                pw.println("-------------------------------------------------------------------------------");
8756            }
8757            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8758        }
8759        Binder.restoreCallingIdentity(origId);
8760    }
8761
8762    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8763            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8764        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8765        pw.println("  Main stack:");
8766        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8767                dumpPackage);
8768        pw.println(" ");
8769        pw.println("  Running activities (most recent first):");
8770        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8771                dumpPackage);
8772        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8773            pw.println(" ");
8774            pw.println("  Activities waiting for another to become visible:");
8775            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8776                    !dumpAll, false, dumpPackage);
8777        }
8778        if (mMainStack.mStoppingActivities.size() > 0) {
8779            pw.println(" ");
8780            pw.println("  Activities waiting to stop:");
8781            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8782                    !dumpAll, false, dumpPackage);
8783        }
8784        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8785            pw.println(" ");
8786            pw.println("  Activities waiting to sleep:");
8787            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8788                    !dumpAll, false, dumpPackage);
8789        }
8790        if (mMainStack.mFinishingActivities.size() > 0) {
8791            pw.println(" ");
8792            pw.println("  Activities waiting to finish:");
8793            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8794                    !dumpAll, false, dumpPackage);
8795        }
8796
8797        pw.println(" ");
8798        if (mMainStack.mPausingActivity != null) {
8799            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8800        }
8801        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8802        pw.println("  mFocusedActivity: " + mFocusedActivity);
8803        if (dumpAll) {
8804            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8805            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8806            pw.println("  mDismissKeyguardOnNextActivity: "
8807                    + mMainStack.mDismissKeyguardOnNextActivity);
8808        }
8809
8810        if (mRecentTasks.size() > 0) {
8811            pw.println();
8812            pw.println("  Recent tasks:");
8813
8814            final int N = mRecentTasks.size();
8815            for (int i=0; i<N; i++) {
8816                TaskRecord tr = mRecentTasks.get(i);
8817                if (dumpPackage != null) {
8818                    if (tr.realActivity == null ||
8819                            !dumpPackage.equals(tr.realActivity)) {
8820                        continue;
8821                    }
8822                }
8823                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8824                        pw.println(tr);
8825                if (dumpAll) {
8826                    mRecentTasks.get(i).dump(pw, "    ");
8827                }
8828            }
8829        }
8830
8831        if (dumpAll) {
8832            pw.println(" ");
8833            pw.println("  mCurTask: " + mCurTask);
8834        }
8835
8836        return true;
8837    }
8838
8839    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8840            int opti, boolean dumpAll, String dumpPackage) {
8841        boolean needSep = false;
8842        int numPers = 0;
8843
8844        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8845
8846        if (dumpAll) {
8847            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8848                final int NA = procs.size();
8849                for (int ia=0; ia<NA; ia++) {
8850                    ProcessRecord r = procs.valueAt(ia);
8851                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8852                        continue;
8853                    }
8854                    if (!needSep) {
8855                        pw.println("  All known processes:");
8856                        needSep = true;
8857                    }
8858                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8859                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8860                        pw.print(" "); pw.println(r);
8861                    r.dump(pw, "    ");
8862                    if (r.persistent) {
8863                        numPers++;
8864                    }
8865                }
8866            }
8867        }
8868
8869        if (mIsolatedProcesses.size() > 0) {
8870            if (needSep) pw.println(" ");
8871            needSep = true;
8872            pw.println("  Isolated process list (sorted by uid):");
8873            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8874                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8875                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8876                    continue;
8877                }
8878                pw.println(String.format("%sIsolated #%2d: %s",
8879                        "    ", i, r.toString()));
8880            }
8881        }
8882
8883        if (mLruProcesses.size() > 0) {
8884            if (needSep) pw.println(" ");
8885            needSep = true;
8886            pw.println("  Process LRU list (sorted by oom_adj):");
8887            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8888                    "Proc", "PERS", false, dumpPackage);
8889            needSep = true;
8890        }
8891
8892        if (dumpAll) {
8893            synchronized (mPidsSelfLocked) {
8894                boolean printed = false;
8895                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8896                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8897                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8898                        continue;
8899                    }
8900                    if (!printed) {
8901                        if (needSep) pw.println(" ");
8902                        needSep = true;
8903                        pw.println("  PID mappings:");
8904                        printed = true;
8905                    }
8906                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8907                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8908                }
8909            }
8910        }
8911
8912        if (mForegroundProcesses.size() > 0) {
8913            synchronized (mPidsSelfLocked) {
8914                boolean printed = false;
8915                for (int i=0; i<mForegroundProcesses.size(); i++) {
8916                    ProcessRecord r = mPidsSelfLocked.get(
8917                            mForegroundProcesses.valueAt(i).pid);
8918                    if (dumpPackage != null && (r == null
8919                            || !dumpPackage.equals(r.info.packageName))) {
8920                        continue;
8921                    }
8922                    if (!printed) {
8923                        if (needSep) pw.println(" ");
8924                        needSep = true;
8925                        pw.println("  Foreground Processes:");
8926                        printed = true;
8927                    }
8928                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8929                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8930                }
8931            }
8932        }
8933
8934        if (mPersistentStartingProcesses.size() > 0) {
8935            if (needSep) pw.println(" ");
8936            needSep = true;
8937            pw.println("  Persisent processes that are starting:");
8938            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8939                    "Starting Norm", "Restarting PERS", dumpPackage);
8940        }
8941
8942        if (mRemovedProcesses.size() > 0) {
8943            if (needSep) pw.println(" ");
8944            needSep = true;
8945            pw.println("  Processes that are being removed:");
8946            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8947                    "Removed Norm", "Removed PERS", dumpPackage);
8948        }
8949
8950        if (mProcessesOnHold.size() > 0) {
8951            if (needSep) pw.println(" ");
8952            needSep = true;
8953            pw.println("  Processes that are on old until the system is ready:");
8954            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8955                    "OnHold Norm", "OnHold PERS", dumpPackage);
8956        }
8957
8958        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8959
8960        if (mProcessCrashTimes.getMap().size() > 0) {
8961            boolean printed = false;
8962            long now = SystemClock.uptimeMillis();
8963            for (Map.Entry<String, SparseArray<Long>> procs
8964                    : mProcessCrashTimes.getMap().entrySet()) {
8965                String pname = procs.getKey();
8966                SparseArray<Long> uids = procs.getValue();
8967                final int N = uids.size();
8968                for (int i=0; i<N; i++) {
8969                    int puid = uids.keyAt(i);
8970                    ProcessRecord r = mProcessNames.get(pname, puid);
8971                    if (dumpPackage != null && (r == null
8972                            || !dumpPackage.equals(r.info.packageName))) {
8973                        continue;
8974                    }
8975                    if (!printed) {
8976                        if (needSep) pw.println(" ");
8977                        needSep = true;
8978                        pw.println("  Time since processes crashed:");
8979                        printed = true;
8980                    }
8981                    pw.print("    Process "); pw.print(pname);
8982                            pw.print(" uid "); pw.print(puid);
8983                            pw.print(": last crashed ");
8984                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8985                            pw.println(" ago");
8986                }
8987            }
8988        }
8989
8990        if (mBadProcesses.getMap().size() > 0) {
8991            boolean printed = false;
8992            for (Map.Entry<String, SparseArray<Long>> procs
8993                    : mBadProcesses.getMap().entrySet()) {
8994                String pname = procs.getKey();
8995                SparseArray<Long> uids = procs.getValue();
8996                final int N = uids.size();
8997                for (int i=0; i<N; i++) {
8998                    int puid = uids.keyAt(i);
8999                    ProcessRecord r = mProcessNames.get(pname, puid);
9000                    if (dumpPackage != null && (r == null
9001                            || !dumpPackage.equals(r.info.packageName))) {
9002                        continue;
9003                    }
9004                    if (!printed) {
9005                        if (needSep) pw.println(" ");
9006                        needSep = true;
9007                        pw.println("  Bad processes:");
9008                    }
9009                    pw.print("    Bad process "); pw.print(pname);
9010                            pw.print(" uid "); pw.print(puid);
9011                            pw.print(": crashed at time ");
9012                            pw.println(uids.valueAt(i));
9013                }
9014            }
9015        }
9016
9017        pw.println();
9018        pw.println("  mHomeProcess: " + mHomeProcess);
9019        pw.println("  mPreviousProcess: " + mPreviousProcess);
9020        if (dumpAll) {
9021            StringBuilder sb = new StringBuilder(128);
9022            sb.append("  mPreviousProcessVisibleTime: ");
9023            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9024            pw.println(sb);
9025        }
9026        if (mHeavyWeightProcess != null) {
9027            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9028        }
9029        pw.println("  mConfiguration: " + mConfiguration);
9030        if (dumpAll) {
9031            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9032            if (mCompatModePackages.getPackages().size() > 0) {
9033                boolean printed = false;
9034                for (Map.Entry<String, Integer> entry
9035                        : mCompatModePackages.getPackages().entrySet()) {
9036                    String pkg = entry.getKey();
9037                    int mode = entry.getValue();
9038                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9039                        continue;
9040                    }
9041                    if (!printed) {
9042                        pw.println("  mScreenCompatPackages:");
9043                        printed = true;
9044                    }
9045                    pw.print("    "); pw.print(pkg); pw.print(": ");
9046                            pw.print(mode); pw.println();
9047                }
9048            }
9049        }
9050        if (mSleeping || mWentToSleep || mLockScreenShown) {
9051            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9052                    + " mLockScreenShown " + mLockScreenShown);
9053        }
9054        if (mShuttingDown) {
9055            pw.println("  mShuttingDown=" + mShuttingDown);
9056        }
9057        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9058                || mOrigWaitForDebugger) {
9059            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9060                    + " mDebugTransient=" + mDebugTransient
9061                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9062        }
9063        if (mOpenGlTraceApp != null) {
9064            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9065        }
9066        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9067                || mProfileFd != null) {
9068            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9069            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9070            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9071                    + mAutoStopProfiler);
9072        }
9073        if (mAlwaysFinishActivities || mController != null) {
9074            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9075                    + " mController=" + mController);
9076        }
9077        if (dumpAll) {
9078            pw.println("  Total persistent processes: " + numPers);
9079            pw.println("  mStartRunning=" + mStartRunning
9080                    + " mProcessesReady=" + mProcessesReady
9081                    + " mSystemReady=" + mSystemReady);
9082            pw.println("  mBooting=" + mBooting
9083                    + " mBooted=" + mBooted
9084                    + " mFactoryTest=" + mFactoryTest);
9085            pw.print("  mLastPowerCheckRealtime=");
9086                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9087                    pw.println("");
9088            pw.print("  mLastPowerCheckUptime=");
9089                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9090                    pw.println("");
9091            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9092            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9093            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9094            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9095                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9096        }
9097
9098        return true;
9099    }
9100
9101    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9102            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9103        if (mProcessesToGc.size() > 0) {
9104            boolean printed = false;
9105            long now = SystemClock.uptimeMillis();
9106            for (int i=0; i<mProcessesToGc.size(); i++) {
9107                ProcessRecord proc = mProcessesToGc.get(i);
9108                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9109                    continue;
9110                }
9111                if (!printed) {
9112                    if (needSep) pw.println(" ");
9113                    needSep = true;
9114                    pw.println("  Processes that are waiting to GC:");
9115                    printed = true;
9116                }
9117                pw.print("    Process "); pw.println(proc);
9118                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9119                        pw.print(", last gced=");
9120                        pw.print(now-proc.lastRequestedGc);
9121                        pw.print(" ms ago, last lowMem=");
9122                        pw.print(now-proc.lastLowMemory);
9123                        pw.println(" ms ago");
9124
9125            }
9126        }
9127        return needSep;
9128    }
9129
9130    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9131            int opti, boolean dumpAll) {
9132        boolean needSep = false;
9133
9134        if (mLruProcesses.size() > 0) {
9135            if (needSep) pw.println(" ");
9136            needSep = true;
9137            pw.println("  OOM levels:");
9138            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9139            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9140            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9141            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9142            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9143            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9144            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9145            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9146            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9147            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9148            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9149            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9150            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9151
9152            if (needSep) pw.println(" ");
9153            needSep = true;
9154            pw.println("  Process OOM control:");
9155            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9156                    "Proc", "PERS", true, null);
9157            needSep = true;
9158        }
9159
9160        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9161
9162        pw.println();
9163        pw.println("  mHomeProcess: " + mHomeProcess);
9164        pw.println("  mPreviousProcess: " + mPreviousProcess);
9165        if (mHeavyWeightProcess != null) {
9166            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9167        }
9168
9169        return true;
9170    }
9171
9172    /**
9173     * There are three ways to call this:
9174     *  - no provider specified: dump all the providers
9175     *  - a flattened component name that matched an existing provider was specified as the
9176     *    first arg: dump that one provider
9177     *  - the first arg isn't the flattened component name of an existing provider:
9178     *    dump all providers whose component contains the first arg as a substring
9179     */
9180    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9181            int opti, boolean dumpAll) {
9182        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9183    }
9184
9185    static class ItemMatcher {
9186        ArrayList<ComponentName> components;
9187        ArrayList<String> strings;
9188        ArrayList<Integer> objects;
9189        boolean all;
9190
9191        ItemMatcher() {
9192            all = true;
9193        }
9194
9195        void build(String name) {
9196            ComponentName componentName = ComponentName.unflattenFromString(name);
9197            if (componentName != null) {
9198                if (components == null) {
9199                    components = new ArrayList<ComponentName>();
9200                }
9201                components.add(componentName);
9202                all = false;
9203            } else {
9204                int objectId = 0;
9205                // Not a '/' separated full component name; maybe an object ID?
9206                try {
9207                    objectId = Integer.parseInt(name, 16);
9208                    if (objects == null) {
9209                        objects = new ArrayList<Integer>();
9210                    }
9211                    objects.add(objectId);
9212                    all = false;
9213                } catch (RuntimeException e) {
9214                    // Not an integer; just do string match.
9215                    if (strings == null) {
9216                        strings = new ArrayList<String>();
9217                    }
9218                    strings.add(name);
9219                    all = false;
9220                }
9221            }
9222        }
9223
9224        int build(String[] args, int opti) {
9225            for (; opti<args.length; opti++) {
9226                String name = args[opti];
9227                if ("--".equals(name)) {
9228                    return opti+1;
9229                }
9230                build(name);
9231            }
9232            return opti;
9233        }
9234
9235        boolean match(Object object, ComponentName comp) {
9236            if (all) {
9237                return true;
9238            }
9239            if (components != null) {
9240                for (int i=0; i<components.size(); i++) {
9241                    if (components.get(i).equals(comp)) {
9242                        return true;
9243                    }
9244                }
9245            }
9246            if (objects != null) {
9247                for (int i=0; i<objects.size(); i++) {
9248                    if (System.identityHashCode(object) == objects.get(i)) {
9249                        return true;
9250                    }
9251                }
9252            }
9253            if (strings != null) {
9254                String flat = comp.flattenToString();
9255                for (int i=0; i<strings.size(); i++) {
9256                    if (flat.contains(strings.get(i))) {
9257                        return true;
9258                    }
9259                }
9260            }
9261            return false;
9262        }
9263    }
9264
9265    /**
9266     * There are three things that cmd can be:
9267     *  - a flattened component name that matches an existing activity
9268     *  - the cmd arg isn't the flattened component name of an existing activity:
9269     *    dump all activity whose component contains the cmd as a substring
9270     *  - A hex number of the ActivityRecord object instance.
9271     */
9272    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9273            int opti, boolean dumpAll) {
9274        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9275
9276        if ("all".equals(name)) {
9277            synchronized (this) {
9278                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9279                    activities.add(r1);
9280                }
9281            }
9282        } else if ("top".equals(name)) {
9283            synchronized (this) {
9284                final int N = mMainStack.mHistory.size();
9285                if (N > 0) {
9286                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9287                }
9288            }
9289        } else {
9290            ItemMatcher matcher = new ItemMatcher();
9291            matcher.build(name);
9292
9293            synchronized (this) {
9294                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9295                    if (matcher.match(r1, r1.intent.getComponent())) {
9296                        activities.add(r1);
9297                    }
9298                }
9299            }
9300        }
9301
9302        if (activities.size() <= 0) {
9303            return false;
9304        }
9305
9306        String[] newArgs = new String[args.length - opti];
9307        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9308
9309        TaskRecord lastTask = null;
9310        boolean needSep = false;
9311        for (int i=activities.size()-1; i>=0; i--) {
9312            ActivityRecord r = (ActivityRecord)activities.get(i);
9313            if (needSep) {
9314                pw.println();
9315            }
9316            needSep = true;
9317            synchronized (this) {
9318                if (lastTask != r.task) {
9319                    lastTask = r.task;
9320                    pw.print("TASK "); pw.print(lastTask.affinity);
9321                            pw.print(" id="); pw.println(lastTask.taskId);
9322                    if (dumpAll) {
9323                        lastTask.dump(pw, "  ");
9324                    }
9325                }
9326            }
9327            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9328        }
9329        return true;
9330    }
9331
9332    /**
9333     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9334     * there is a thread associated with the activity.
9335     */
9336    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9337            final ActivityRecord r, String[] args, boolean dumpAll) {
9338        String innerPrefix = prefix + "  ";
9339        synchronized (this) {
9340            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9341                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9342                    pw.print(" pid=");
9343                    if (r.app != null) pw.println(r.app.pid);
9344                    else pw.println("(not running)");
9345            if (dumpAll) {
9346                r.dump(pw, innerPrefix);
9347            }
9348        }
9349        if (r.app != null && r.app.thread != null) {
9350            // flush anything that is already in the PrintWriter since the thread is going
9351            // to write to the file descriptor directly
9352            pw.flush();
9353            try {
9354                TransferPipe tp = new TransferPipe();
9355                try {
9356                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9357                            r.appToken, innerPrefix, args);
9358                    tp.go(fd);
9359                } finally {
9360                    tp.kill();
9361                }
9362            } catch (IOException e) {
9363                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9364            } catch (RemoteException e) {
9365                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9366            }
9367        }
9368    }
9369
9370    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9371            int opti, boolean dumpAll, String dumpPackage) {
9372        boolean needSep = false;
9373
9374        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9375        if (dumpAll) {
9376            if (mRegisteredReceivers.size() > 0) {
9377                boolean printed = false;
9378                Iterator it = mRegisteredReceivers.values().iterator();
9379                while (it.hasNext()) {
9380                    ReceiverList r = (ReceiverList)it.next();
9381                    if (dumpPackage != null && (r.app == null ||
9382                            !dumpPackage.equals(r.app.info.packageName))) {
9383                        continue;
9384                    }
9385                    if (!printed) {
9386                        pw.println("  Registered Receivers:");
9387                        needSep = true;
9388                        printed = true;
9389                    }
9390                    pw.print("  * "); pw.println(r);
9391                    r.dump(pw, "    ");
9392                }
9393            }
9394
9395            if (mReceiverResolver.dump(pw, needSep ?
9396                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9397                    "    ", dumpPackage, false)) {
9398                needSep = true;
9399            }
9400        }
9401
9402        for (BroadcastQueue q : mBroadcastQueues) {
9403            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9404        }
9405
9406        needSep = true;
9407
9408        if (mStickyBroadcasts != null && dumpPackage == null) {
9409            if (needSep) {
9410                pw.println();
9411            }
9412            needSep = true;
9413            pw.println("  Sticky broadcasts:");
9414            StringBuilder sb = new StringBuilder(128);
9415            for (Map.Entry<String, ArrayList<Intent>> ent
9416                    : mStickyBroadcasts.entrySet()) {
9417                pw.print("  * Sticky action "); pw.print(ent.getKey());
9418                if (dumpAll) {
9419                    pw.println(":");
9420                    ArrayList<Intent> intents = ent.getValue();
9421                    final int N = intents.size();
9422                    for (int i=0; i<N; i++) {
9423                        sb.setLength(0);
9424                        sb.append("    Intent: ");
9425                        intents.get(i).toShortString(sb, false, true, false, false);
9426                        pw.println(sb.toString());
9427                        Bundle bundle = intents.get(i).getExtras();
9428                        if (bundle != null) {
9429                            pw.print("      ");
9430                            pw.println(bundle.toString());
9431                        }
9432                    }
9433                } else {
9434                    pw.println("");
9435                }
9436            }
9437            needSep = true;
9438        }
9439
9440        if (dumpAll) {
9441            pw.println();
9442            for (BroadcastQueue queue : mBroadcastQueues) {
9443                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9444                        + queue.mBroadcastsScheduled);
9445            }
9446            pw.println("  mHandler:");
9447            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9448            needSep = true;
9449        }
9450
9451        return needSep;
9452    }
9453
9454    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9455            int opti, boolean dumpAll, String dumpPackage) {
9456        boolean needSep = true;
9457
9458        ItemMatcher matcher = new ItemMatcher();
9459        matcher.build(args, opti);
9460
9461        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9462
9463        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9464
9465        if (mLaunchingProviders.size() > 0) {
9466            boolean printed = false;
9467            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9468                ContentProviderRecord r = mLaunchingProviders.get(i);
9469                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9470                    continue;
9471                }
9472                if (!printed) {
9473                    if (needSep) pw.println(" ");
9474                    needSep = true;
9475                    pw.println("  Launching content providers:");
9476                    printed = true;
9477                }
9478                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9479                        pw.println(r);
9480            }
9481        }
9482
9483        if (mGrantedUriPermissions.size() > 0) {
9484            if (needSep) pw.println();
9485            needSep = true;
9486            pw.println("Granted Uri Permissions:");
9487            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9488                int uid = mGrantedUriPermissions.keyAt(i);
9489                HashMap<Uri, UriPermission> perms
9490                        = mGrantedUriPermissions.valueAt(i);
9491                pw.print("  * UID "); pw.print(uid);
9492                        pw.println(" holds:");
9493                for (UriPermission perm : perms.values()) {
9494                    pw.print("    "); pw.println(perm);
9495                    if (dumpAll) {
9496                        perm.dump(pw, "      ");
9497                    }
9498                }
9499            }
9500            needSep = true;
9501        }
9502
9503        return needSep;
9504    }
9505
9506    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9507            int opti, boolean dumpAll, String dumpPackage) {
9508        boolean needSep = false;
9509
9510        if (mIntentSenderRecords.size() > 0) {
9511            boolean printed = false;
9512            Iterator<WeakReference<PendingIntentRecord>> it
9513                    = mIntentSenderRecords.values().iterator();
9514            while (it.hasNext()) {
9515                WeakReference<PendingIntentRecord> ref = it.next();
9516                PendingIntentRecord rec = ref != null ? ref.get(): null;
9517                if (dumpPackage != null && (rec == null
9518                        || !dumpPackage.equals(rec.key.packageName))) {
9519                    continue;
9520                }
9521                if (!printed) {
9522                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9523                    printed = true;
9524                }
9525                needSep = true;
9526                if (rec != null) {
9527                    pw.print("  * "); pw.println(rec);
9528                    if (dumpAll) {
9529                        rec.dump(pw, "    ");
9530                    }
9531                } else {
9532                    pw.print("  * "); pw.println(ref);
9533                }
9534            }
9535        }
9536
9537        return needSep;
9538    }
9539
9540    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9541            String prefix, String label, boolean complete, boolean brief, boolean client,
9542            String dumpPackage) {
9543        TaskRecord lastTask = null;
9544        boolean needNL = false;
9545        final String innerPrefix = prefix + "      ";
9546        final String[] args = new String[0];
9547        for (int i=list.size()-1; i>=0; i--) {
9548            final ActivityRecord r = (ActivityRecord)list.get(i);
9549            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9550                continue;
9551            }
9552            final boolean full = !brief && (complete || !r.isInHistory());
9553            if (needNL) {
9554                pw.println(" ");
9555                needNL = false;
9556            }
9557            if (lastTask != r.task) {
9558                lastTask = r.task;
9559                pw.print(prefix);
9560                pw.print(full ? "* " : "  ");
9561                pw.println(lastTask);
9562                if (full) {
9563                    lastTask.dump(pw, prefix + "  ");
9564                } else if (complete) {
9565                    // Complete + brief == give a summary.  Isn't that obvious?!?
9566                    if (lastTask.intent != null) {
9567                        pw.print(prefix); pw.print("  ");
9568                                pw.println(lastTask.intent.toInsecureStringWithClip());
9569                    }
9570                }
9571            }
9572            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9573            pw.print(" #"); pw.print(i); pw.print(": ");
9574            pw.println(r);
9575            if (full) {
9576                r.dump(pw, innerPrefix);
9577            } else if (complete) {
9578                // Complete + brief == give a summary.  Isn't that obvious?!?
9579                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9580                if (r.app != null) {
9581                    pw.print(innerPrefix); pw.println(r.app);
9582                }
9583            }
9584            if (client && r.app != null && r.app.thread != null) {
9585                // flush anything that is already in the PrintWriter since the thread is going
9586                // to write to the file descriptor directly
9587                pw.flush();
9588                try {
9589                    TransferPipe tp = new TransferPipe();
9590                    try {
9591                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9592                                r.appToken, innerPrefix, args);
9593                        // Short timeout, since blocking here can
9594                        // deadlock with the application.
9595                        tp.go(fd, 2000);
9596                    } finally {
9597                        tp.kill();
9598                    }
9599                } catch (IOException e) {
9600                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9601                } catch (RemoteException e) {
9602                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9603                }
9604                needNL = true;
9605            }
9606        }
9607    }
9608
9609    private static String buildOomTag(String prefix, String space, int val, int base) {
9610        if (val == base) {
9611            if (space == null) return prefix;
9612            return prefix + "  ";
9613        }
9614        return prefix + "+" + Integer.toString(val-base);
9615    }
9616
9617    private static final int dumpProcessList(PrintWriter pw,
9618            ActivityManagerService service, List list,
9619            String prefix, String normalLabel, String persistentLabel,
9620            String dumpPackage) {
9621        int numPers = 0;
9622        final int N = list.size()-1;
9623        for (int i=N; i>=0; i--) {
9624            ProcessRecord r = (ProcessRecord)list.get(i);
9625            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9626                continue;
9627            }
9628            pw.println(String.format("%s%s #%2d: %s",
9629                    prefix, (r.persistent ? persistentLabel : normalLabel),
9630                    i, r.toString()));
9631            if (r.persistent) {
9632                numPers++;
9633            }
9634        }
9635        return numPers;
9636    }
9637
9638    private static final boolean dumpProcessOomList(PrintWriter pw,
9639            ActivityManagerService service, List<ProcessRecord> origList,
9640            String prefix, String normalLabel, String persistentLabel,
9641            boolean inclDetails, String dumpPackage) {
9642
9643        ArrayList<Pair<ProcessRecord, Integer>> list
9644                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9645        for (int i=0; i<origList.size(); i++) {
9646            ProcessRecord r = origList.get(i);
9647            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9648                continue;
9649            }
9650            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9651        }
9652
9653        if (list.size() <= 0) {
9654            return false;
9655        }
9656
9657        Comparator<Pair<ProcessRecord, Integer>> comparator
9658                = new Comparator<Pair<ProcessRecord, Integer>>() {
9659            @Override
9660            public int compare(Pair<ProcessRecord, Integer> object1,
9661                    Pair<ProcessRecord, Integer> object2) {
9662                if (object1.first.setAdj != object2.first.setAdj) {
9663                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9664                }
9665                if (object1.second.intValue() != object2.second.intValue()) {
9666                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9667                }
9668                return 0;
9669            }
9670        };
9671
9672        Collections.sort(list, comparator);
9673
9674        final long curRealtime = SystemClock.elapsedRealtime();
9675        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9676        final long curUptime = SystemClock.uptimeMillis();
9677        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9678
9679        for (int i=list.size()-1; i>=0; i--) {
9680            ProcessRecord r = list.get(i).first;
9681            String oomAdj;
9682            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9683                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9684            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9685                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9686            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9687                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9688            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9689                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9690            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9691                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9692            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9693                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9694            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9695                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9696            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9697                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9698            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9699                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9700            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9701                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9702            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9703                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9704            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9705                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9706            } else {
9707                oomAdj = Integer.toString(r.setAdj);
9708            }
9709            String schedGroup;
9710            switch (r.setSchedGroup) {
9711                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9712                    schedGroup = "B";
9713                    break;
9714                case Process.THREAD_GROUP_DEFAULT:
9715                    schedGroup = "F";
9716                    break;
9717                default:
9718                    schedGroup = Integer.toString(r.setSchedGroup);
9719                    break;
9720            }
9721            String foreground;
9722            if (r.foregroundActivities) {
9723                foreground = "A";
9724            } else if (r.foregroundServices) {
9725                foreground = "S";
9726            } else {
9727                foreground = " ";
9728            }
9729            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9730                    prefix, (r.persistent ? persistentLabel : normalLabel),
9731                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9732                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9733            if (r.adjSource != null || r.adjTarget != null) {
9734                pw.print(prefix);
9735                pw.print("    ");
9736                if (r.adjTarget instanceof ComponentName) {
9737                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9738                } else if (r.adjTarget != null) {
9739                    pw.print(r.adjTarget.toString());
9740                } else {
9741                    pw.print("{null}");
9742                }
9743                pw.print("<=");
9744                if (r.adjSource instanceof ProcessRecord) {
9745                    pw.print("Proc{");
9746                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9747                    pw.println("}");
9748                } else if (r.adjSource != null) {
9749                    pw.println(r.adjSource.toString());
9750                } else {
9751                    pw.println("{null}");
9752                }
9753            }
9754            if (inclDetails) {
9755                pw.print(prefix);
9756                pw.print("    ");
9757                pw.print("oom: max="); pw.print(r.maxAdj);
9758                pw.print(" hidden="); pw.print(r.hiddenAdj);
9759                pw.print(" curRaw="); pw.print(r.curRawAdj);
9760                pw.print(" setRaw="); pw.print(r.setRawAdj);
9761                pw.print(" cur="); pw.print(r.curAdj);
9762                pw.print(" set="); pw.println(r.setAdj);
9763                pw.print(prefix);
9764                pw.print("    ");
9765                pw.print("keeping="); pw.print(r.keeping);
9766                pw.print(" hidden="); pw.print(r.hidden);
9767                pw.print(" empty="); pw.print(r.empty);
9768                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9769
9770                if (!r.keeping) {
9771                    if (r.lastWakeTime != 0) {
9772                        long wtime;
9773                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9774                        synchronized (stats) {
9775                            wtime = stats.getProcessWakeTime(r.info.uid,
9776                                    r.pid, curRealtime);
9777                        }
9778                        long timeUsed = wtime - r.lastWakeTime;
9779                        pw.print(prefix);
9780                        pw.print("    ");
9781                        pw.print("keep awake over ");
9782                        TimeUtils.formatDuration(realtimeSince, pw);
9783                        pw.print(" used ");
9784                        TimeUtils.formatDuration(timeUsed, pw);
9785                        pw.print(" (");
9786                        pw.print((timeUsed*100)/realtimeSince);
9787                        pw.println("%)");
9788                    }
9789                    if (r.lastCpuTime != 0) {
9790                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9791                        pw.print(prefix);
9792                        pw.print("    ");
9793                        pw.print("run cpu over ");
9794                        TimeUtils.formatDuration(uptimeSince, pw);
9795                        pw.print(" used ");
9796                        TimeUtils.formatDuration(timeUsed, pw);
9797                        pw.print(" (");
9798                        pw.print((timeUsed*100)/uptimeSince);
9799                        pw.println("%)");
9800                    }
9801                }
9802            }
9803        }
9804        return true;
9805    }
9806
9807    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9808        ArrayList<ProcessRecord> procs;
9809        synchronized (this) {
9810            if (args != null && args.length > start
9811                    && args[start].charAt(0) != '-') {
9812                procs = new ArrayList<ProcessRecord>();
9813                int pid = -1;
9814                try {
9815                    pid = Integer.parseInt(args[start]);
9816                } catch (NumberFormatException e) {
9817
9818                }
9819                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9820                    ProcessRecord proc = mLruProcesses.get(i);
9821                    if (proc.pid == pid) {
9822                        procs.add(proc);
9823                    } else if (proc.processName.equals(args[start])) {
9824                        procs.add(proc);
9825                    }
9826                }
9827                if (procs.size() <= 0) {
9828                    pw.println("No process found for: " + args[start]);
9829                    return null;
9830                }
9831            } else {
9832                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9833            }
9834        }
9835        return procs;
9836    }
9837
9838    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9839            PrintWriter pw, String[] args) {
9840        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9841        if (procs == null) {
9842            return;
9843        }
9844
9845        long uptime = SystemClock.uptimeMillis();
9846        long realtime = SystemClock.elapsedRealtime();
9847        pw.println("Applications Graphics Acceleration Info:");
9848        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9849
9850        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9851            ProcessRecord r = procs.get(i);
9852            if (r.thread != null) {
9853                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9854                pw.flush();
9855                try {
9856                    TransferPipe tp = new TransferPipe();
9857                    try {
9858                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9859                        tp.go(fd);
9860                    } finally {
9861                        tp.kill();
9862                    }
9863                } catch (IOException e) {
9864                    pw.println("Failure while dumping the app: " + r);
9865                    pw.flush();
9866                } catch (RemoteException e) {
9867                    pw.println("Got a RemoteException while dumping the app " + r);
9868                    pw.flush();
9869                }
9870            }
9871        }
9872    }
9873
9874    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9875        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9876        if (procs == null) {
9877            return;
9878        }
9879
9880        pw.println("Applications Database Info:");
9881
9882        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9883            ProcessRecord r = procs.get(i);
9884            if (r.thread != null) {
9885                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9886                pw.flush();
9887                try {
9888                    TransferPipe tp = new TransferPipe();
9889                    try {
9890                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9891                        tp.go(fd);
9892                    } finally {
9893                        tp.kill();
9894                    }
9895                } catch (IOException e) {
9896                    pw.println("Failure while dumping the app: " + r);
9897                    pw.flush();
9898                } catch (RemoteException e) {
9899                    pw.println("Got a RemoteException while dumping the app " + r);
9900                    pw.flush();
9901                }
9902            }
9903        }
9904    }
9905
9906    final static class MemItem {
9907        final String label;
9908        final String shortLabel;
9909        final long pss;
9910        final int id;
9911        ArrayList<MemItem> subitems;
9912
9913        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9914            label = _label;
9915            shortLabel = _shortLabel;
9916            pss = _pss;
9917            id = _id;
9918        }
9919    }
9920
9921    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9922            boolean sort) {
9923        if (sort) {
9924            Collections.sort(items, new Comparator<MemItem>() {
9925                @Override
9926                public int compare(MemItem lhs, MemItem rhs) {
9927                    if (lhs.pss < rhs.pss) {
9928                        return 1;
9929                    } else if (lhs.pss > rhs.pss) {
9930                        return -1;
9931                    }
9932                    return 0;
9933                }
9934            });
9935        }
9936
9937        for (int i=0; i<items.size(); i++) {
9938            MemItem mi = items.get(i);
9939            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9940            if (mi.subitems != null) {
9941                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9942            }
9943        }
9944    }
9945
9946    // These are in KB.
9947    static final long[] DUMP_MEM_BUCKETS = new long[] {
9948        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9949        120*1024, 160*1024, 200*1024,
9950        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9951        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9952    };
9953
9954    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9955            boolean stackLike) {
9956        int start = label.lastIndexOf('.');
9957        if (start >= 0) start++;
9958        else start = 0;
9959        int end = label.length();
9960        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9961            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9962                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9963                out.append(bucket);
9964                out.append(stackLike ? "MB." : "MB ");
9965                out.append(label, start, end);
9966                return;
9967            }
9968        }
9969        out.append(memKB/1024);
9970        out.append(stackLike ? "MB." : "MB ");
9971        out.append(label, start, end);
9972    }
9973
9974    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9975            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9976            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9977            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9978            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9979    };
9980    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9981            "System", "Persistent", "Foreground",
9982            "Visible", "Perceptible", "Heavy Weight",
9983            "Backup", "A Services", "Home", "Previous",
9984            "B Services", "Background"
9985    };
9986
9987    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9988            PrintWriter pw, String prefix, String[] args, boolean brief,
9989            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9990        boolean dumpAll = false;
9991        boolean oomOnly = false;
9992
9993        int opti = 0;
9994        while (opti < args.length) {
9995            String opt = args[opti];
9996            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9997                break;
9998            }
9999            opti++;
10000            if ("-a".equals(opt)) {
10001                dumpAll = true;
10002            } else if ("--oom".equals(opt)) {
10003                oomOnly = true;
10004            } else if ("-h".equals(opt)) {
10005                pw.println("meminfo dump options: [-a] [--oom] [process]");
10006                pw.println("  -a: include all available information for each process.");
10007                pw.println("  --oom: only show processes organized by oom adj.");
10008                pw.println("If [process] is specified it can be the name or ");
10009                pw.println("pid of a specific process to dump.");
10010                return;
10011            } else {
10012                pw.println("Unknown argument: " + opt + "; use -h for help");
10013            }
10014        }
10015
10016        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10017        if (procs == null) {
10018            return;
10019        }
10020
10021        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10022        long uptime = SystemClock.uptimeMillis();
10023        long realtime = SystemClock.elapsedRealtime();
10024
10025        if (procs.size() == 1 || isCheckinRequest) {
10026            dumpAll = true;
10027        }
10028
10029        if (isCheckinRequest) {
10030            // short checkin version
10031            pw.println(uptime + "," + realtime);
10032            pw.flush();
10033        } else {
10034            pw.println("Applications Memory Usage (kB):");
10035            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10036        }
10037
10038        String[] innerArgs = new String[args.length-opti];
10039        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10040
10041        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10042        long nativePss=0, dalvikPss=0, otherPss=0;
10043        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10044
10045        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10046        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10047                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10048
10049        long totalPss = 0;
10050
10051        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10052            ProcessRecord r = procs.get(i);
10053            if (r.thread != null) {
10054                if (!isCheckinRequest && dumpAll) {
10055                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10056                    pw.flush();
10057                }
10058                Debug.MemoryInfo mi = null;
10059                if (dumpAll) {
10060                    try {
10061                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10062                    } catch (RemoteException e) {
10063                        if (!isCheckinRequest) {
10064                            pw.println("Got RemoteException!");
10065                            pw.flush();
10066                        }
10067                    }
10068                } else {
10069                    mi = new Debug.MemoryInfo();
10070                    Debug.getMemoryInfo(r.pid, mi);
10071                }
10072
10073                if (!isCheckinRequest && mi != null) {
10074                    long myTotalPss = mi.getTotalPss();
10075                    totalPss += myTotalPss;
10076                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10077                            r.processName, myTotalPss, 0);
10078                    procMems.add(pssItem);
10079
10080                    nativePss += mi.nativePss;
10081                    dalvikPss += mi.dalvikPss;
10082                    otherPss += mi.otherPss;
10083                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10084                        long mem = mi.getOtherPss(j);
10085                        miscPss[j] += mem;
10086                        otherPss -= mem;
10087                    }
10088
10089                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10090                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10091                                || oomIndex == (oomPss.length-1)) {
10092                            oomPss[oomIndex] += myTotalPss;
10093                            if (oomProcs[oomIndex] == null) {
10094                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10095                            }
10096                            oomProcs[oomIndex].add(pssItem);
10097                            break;
10098                        }
10099                    }
10100                }
10101            }
10102        }
10103
10104        if (!isCheckinRequest && procs.size() > 1) {
10105            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10106
10107            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10108            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10109            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10110            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10111                String label = Debug.MemoryInfo.getOtherLabel(j);
10112                catMems.add(new MemItem(label, label, miscPss[j], j));
10113            }
10114
10115            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10116            for (int j=0; j<oomPss.length; j++) {
10117                if (oomPss[j] != 0) {
10118                    String label = DUMP_MEM_OOM_LABEL[j];
10119                    MemItem item = new MemItem(label, label, oomPss[j],
10120                            DUMP_MEM_OOM_ADJ[j]);
10121                    item.subitems = oomProcs[j];
10122                    oomMems.add(item);
10123                }
10124            }
10125
10126            if (outTag != null || outStack != null) {
10127                if (outTag != null) {
10128                    appendMemBucket(outTag, totalPss, "total", false);
10129                }
10130                if (outStack != null) {
10131                    appendMemBucket(outStack, totalPss, "total", true);
10132                }
10133                boolean firstLine = true;
10134                for (int i=0; i<oomMems.size(); i++) {
10135                    MemItem miCat = oomMems.get(i);
10136                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10137                        continue;
10138                    }
10139                    if (miCat.id < ProcessList.SERVICE_ADJ
10140                            || miCat.id == ProcessList.HOME_APP_ADJ
10141                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10142                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10143                            outTag.append(" / ");
10144                        }
10145                        if (outStack != null) {
10146                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10147                                if (firstLine) {
10148                                    outStack.append(":");
10149                                    firstLine = false;
10150                                }
10151                                outStack.append("\n\t at ");
10152                            } else {
10153                                outStack.append("$");
10154                            }
10155                        }
10156                        for (int j=0; j<miCat.subitems.size(); j++) {
10157                            MemItem mi = miCat.subitems.get(j);
10158                            if (j > 0) {
10159                                if (outTag != null) {
10160                                    outTag.append(" ");
10161                                }
10162                                if (outStack != null) {
10163                                    outStack.append("$");
10164                                }
10165                            }
10166                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10167                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10168                            }
10169                            if (outStack != null) {
10170                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10171                            }
10172                        }
10173                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10174                            outStack.append("(");
10175                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10176                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10177                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10178                                    outStack.append(":");
10179                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10180                                }
10181                            }
10182                            outStack.append(")");
10183                        }
10184                    }
10185                }
10186            }
10187
10188            if (!brief && !oomOnly) {
10189                pw.println();
10190                pw.println("Total PSS by process:");
10191                dumpMemItems(pw, "  ", procMems, true);
10192                pw.println();
10193            }
10194            pw.println("Total PSS by OOM adjustment:");
10195            dumpMemItems(pw, "  ", oomMems, false);
10196            if (!oomOnly) {
10197                PrintWriter out = categoryPw != null ? categoryPw : pw;
10198                out.println();
10199                out.println("Total PSS by category:");
10200                dumpMemItems(out, "  ", catMems, true);
10201            }
10202            pw.println();
10203            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10204            final int[] SINGLE_LONG_FORMAT = new int[] {
10205                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10206            };
10207            long[] longOut = new long[1];
10208            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10209                    SINGLE_LONG_FORMAT, null, longOut, null);
10210            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10211            longOut[0] = 0;
10212            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10213                    SINGLE_LONG_FORMAT, null, longOut, null);
10214            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10215            longOut[0] = 0;
10216            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10217                    SINGLE_LONG_FORMAT, null, longOut, null);
10218            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10219            longOut[0] = 0;
10220            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10221                    SINGLE_LONG_FORMAT, null, longOut, null);
10222            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10223            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10224                    pw.print(shared); pw.println(" kB");
10225            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10226                    pw.print(voltile); pw.println(" kB volatile");
10227        }
10228    }
10229
10230    /**
10231     * Searches array of arguments for the specified string
10232     * @param args array of argument strings
10233     * @param value value to search for
10234     * @return true if the value is contained in the array
10235     */
10236    private static boolean scanArgs(String[] args, String value) {
10237        if (args != null) {
10238            for (String arg : args) {
10239                if (value.equals(arg)) {
10240                    return true;
10241                }
10242            }
10243        }
10244        return false;
10245    }
10246
10247    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10248            ContentProviderRecord cpr, boolean always) {
10249        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10250
10251        if (!inLaunching || always) {
10252            synchronized (cpr) {
10253                cpr.launchingApp = null;
10254                cpr.notifyAll();
10255            }
10256            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10257            String names[] = cpr.info.authority.split(";");
10258            for (int j = 0; j < names.length; j++) {
10259                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10260            }
10261        }
10262
10263        for (int i=0; i<cpr.connections.size(); i++) {
10264            ContentProviderConnection conn = cpr.connections.get(i);
10265            if (conn.waiting) {
10266                // If this connection is waiting for the provider, then we don't
10267                // need to mess with its process unless we are always removing
10268                // or for some reason the provider is not currently launching.
10269                if (inLaunching && !always) {
10270                    continue;
10271                }
10272            }
10273            ProcessRecord capp = conn.client;
10274            conn.dead = true;
10275            if (conn.stableCount > 0) {
10276                if (!capp.persistent && capp.thread != null
10277                        && capp.pid != 0
10278                        && capp.pid != MY_PID) {
10279                    Slog.i(TAG, "Kill " + capp.processName
10280                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10281                            + " in dying process " + (proc != null ? proc.processName : "??"));
10282                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10283                            capp.processName, capp.setAdj, "dying provider "
10284                                    + cpr.name.toShortString());
10285                    Process.killProcessQuiet(capp.pid);
10286                }
10287            } else if (capp.thread != null && conn.provider.provider != null) {
10288                try {
10289                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10290                } catch (RemoteException e) {
10291                }
10292                // In the protocol here, we don't expect the client to correctly
10293                // clean up this connection, we'll just remove it.
10294                cpr.connections.remove(i);
10295                conn.client.conProviders.remove(conn);
10296            }
10297        }
10298
10299        if (inLaunching && always) {
10300            mLaunchingProviders.remove(cpr);
10301        }
10302        return inLaunching;
10303    }
10304
10305    /**
10306     * Main code for cleaning up a process when it has gone away.  This is
10307     * called both as a result of the process dying, or directly when stopping
10308     * a process when running in single process mode.
10309     */
10310    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10311            boolean restarting, boolean allowRestart, int index) {
10312        if (index >= 0) {
10313            mLruProcesses.remove(index);
10314        }
10315
10316        mProcessesToGc.remove(app);
10317
10318        // Dismiss any open dialogs.
10319        if (app.crashDialog != null) {
10320            app.crashDialog.dismiss();
10321            app.crashDialog = null;
10322        }
10323        if (app.anrDialog != null) {
10324            app.anrDialog.dismiss();
10325            app.anrDialog = null;
10326        }
10327        if (app.waitDialog != null) {
10328            app.waitDialog.dismiss();
10329            app.waitDialog = null;
10330        }
10331
10332        app.crashing = false;
10333        app.notResponding = false;
10334
10335        app.resetPackageList();
10336        app.unlinkDeathRecipient();
10337        app.thread = null;
10338        app.forcingToForeground = null;
10339        app.foregroundServices = false;
10340        app.foregroundActivities = false;
10341        app.hasShownUi = false;
10342        app.hasAboveClient = false;
10343
10344        mServices.killServicesLocked(app, allowRestart);
10345
10346        boolean restart = false;
10347
10348        // Remove published content providers.
10349        if (!app.pubProviders.isEmpty()) {
10350            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10351            while (it.hasNext()) {
10352                ContentProviderRecord cpr = it.next();
10353
10354                final boolean always = app.bad || !allowRestart;
10355                if (removeDyingProviderLocked(app, cpr, always) || always) {
10356                    // We left the provider in the launching list, need to
10357                    // restart it.
10358                    restart = true;
10359                }
10360
10361                cpr.provider = null;
10362                cpr.proc = null;
10363            }
10364            app.pubProviders.clear();
10365        }
10366
10367        // Take care of any launching providers waiting for this process.
10368        if (checkAppInLaunchingProvidersLocked(app, false)) {
10369            restart = true;
10370        }
10371
10372        // Unregister from connected content providers.
10373        if (!app.conProviders.isEmpty()) {
10374            for (int i=0; i<app.conProviders.size(); i++) {
10375                ContentProviderConnection conn = app.conProviders.get(i);
10376                conn.provider.connections.remove(conn);
10377            }
10378            app.conProviders.clear();
10379        }
10380
10381        // At this point there may be remaining entries in mLaunchingProviders
10382        // where we were the only one waiting, so they are no longer of use.
10383        // Look for these and clean up if found.
10384        // XXX Commented out for now.  Trying to figure out a way to reproduce
10385        // the actual situation to identify what is actually going on.
10386        if (false) {
10387            for (int i=0; i<mLaunchingProviders.size(); i++) {
10388                ContentProviderRecord cpr = (ContentProviderRecord)
10389                        mLaunchingProviders.get(i);
10390                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10391                    synchronized (cpr) {
10392                        cpr.launchingApp = null;
10393                        cpr.notifyAll();
10394                    }
10395                }
10396            }
10397        }
10398
10399        skipCurrentReceiverLocked(app);
10400
10401        // Unregister any receivers.
10402        if (app.receivers.size() > 0) {
10403            Iterator<ReceiverList> it = app.receivers.iterator();
10404            while (it.hasNext()) {
10405                removeReceiverLocked(it.next());
10406            }
10407            app.receivers.clear();
10408        }
10409
10410        // If the app is undergoing backup, tell the backup manager about it
10411        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10412            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10413            try {
10414                IBackupManager bm = IBackupManager.Stub.asInterface(
10415                        ServiceManager.getService(Context.BACKUP_SERVICE));
10416                bm.agentDisconnected(app.info.packageName);
10417            } catch (RemoteException e) {
10418                // can't happen; backup manager is local
10419            }
10420        }
10421
10422        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10423            ProcessChangeItem item = mPendingProcessChanges.get(i);
10424            if (item.pid == app.pid) {
10425                mPendingProcessChanges.remove(i);
10426                mAvailProcessChanges.add(item);
10427            }
10428        }
10429        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10430
10431        // If the caller is restarting this app, then leave it in its
10432        // current lists and let the caller take care of it.
10433        if (restarting) {
10434            return;
10435        }
10436
10437        if (!app.persistent || app.isolated) {
10438            if (DEBUG_PROCESSES) Slog.v(TAG,
10439                    "Removing non-persistent process during cleanup: " + app);
10440            mProcessNames.remove(app.processName, app.uid);
10441            mIsolatedProcesses.remove(app.uid);
10442            if (mHeavyWeightProcess == app) {
10443                mHeavyWeightProcess = null;
10444                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10445            }
10446        } else if (!app.removed) {
10447            // This app is persistent, so we need to keep its record around.
10448            // If it is not already on the pending app list, add it there
10449            // and start a new process for it.
10450            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10451                mPersistentStartingProcesses.add(app);
10452                restart = true;
10453            }
10454        }
10455        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10456                "Clean-up removing on hold: " + app);
10457        mProcessesOnHold.remove(app);
10458
10459        if (app == mHomeProcess) {
10460            mHomeProcess = null;
10461        }
10462        if (app == mPreviousProcess) {
10463            mPreviousProcess = null;
10464        }
10465
10466        if (restart && !app.isolated) {
10467            // We have components that still need to be running in the
10468            // process, so re-launch it.
10469            mProcessNames.put(app.processName, app.uid, app);
10470            startProcessLocked(app, "restart", app.processName);
10471        } else if (app.pid > 0 && app.pid != MY_PID) {
10472            // Goodbye!
10473            synchronized (mPidsSelfLocked) {
10474                mPidsSelfLocked.remove(app.pid);
10475                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10476            }
10477            app.setPid(0);
10478        }
10479    }
10480
10481    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10482        // Look through the content providers we are waiting to have launched,
10483        // and if any run in this process then either schedule a restart of
10484        // the process or kill the client waiting for it if this process has
10485        // gone bad.
10486        int NL = mLaunchingProviders.size();
10487        boolean restart = false;
10488        for (int i=0; i<NL; i++) {
10489            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10490            if (cpr.launchingApp == app) {
10491                if (!alwaysBad && !app.bad) {
10492                    restart = true;
10493                } else {
10494                    removeDyingProviderLocked(app, cpr, true);
10495                    NL = mLaunchingProviders.size();
10496                }
10497            }
10498        }
10499        return restart;
10500    }
10501
10502    // =========================================================
10503    // SERVICES
10504    // =========================================================
10505
10506    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10507            int flags) {
10508        enforceNotIsolatedCaller("getServices");
10509        synchronized (this) {
10510            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10511        }
10512    }
10513
10514    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10515        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10516        synchronized (this) {
10517            return mServices.getRunningServiceControlPanelLocked(name);
10518        }
10519    }
10520
10521    public ComponentName startService(IApplicationThread caller, Intent service,
10522            String resolvedType) {
10523        enforceNotIsolatedCaller("startService");
10524        // Refuse possible leaked file descriptors
10525        if (service != null && service.hasFileDescriptors() == true) {
10526            throw new IllegalArgumentException("File descriptors passed in Intent");
10527        }
10528
10529        if (DEBUG_SERVICE)
10530            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10531        synchronized(this) {
10532            final int callingPid = Binder.getCallingPid();
10533            final int callingUid = Binder.getCallingUid();
10534            final long origId = Binder.clearCallingIdentity();
10535            ComponentName res = mServices.startServiceLocked(caller, service,
10536                    resolvedType, callingPid, callingUid);
10537            Binder.restoreCallingIdentity(origId);
10538            return res;
10539        }
10540    }
10541
10542    ComponentName startServiceInPackage(int uid,
10543            Intent service, String resolvedType) {
10544        synchronized(this) {
10545            if (DEBUG_SERVICE)
10546                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10547            final long origId = Binder.clearCallingIdentity();
10548            ComponentName res = mServices.startServiceLocked(null, service,
10549                    resolvedType, -1, uid);
10550            Binder.restoreCallingIdentity(origId);
10551            return res;
10552        }
10553    }
10554
10555    public int stopService(IApplicationThread caller, Intent service,
10556            String resolvedType) {
10557        enforceNotIsolatedCaller("stopService");
10558        // Refuse possible leaked file descriptors
10559        if (service != null && service.hasFileDescriptors() == true) {
10560            throw new IllegalArgumentException("File descriptors passed in Intent");
10561        }
10562
10563        synchronized(this) {
10564            return mServices.stopServiceLocked(caller, service, resolvedType);
10565        }
10566    }
10567
10568    public IBinder peekService(Intent service, String resolvedType) {
10569        enforceNotIsolatedCaller("peekService");
10570        // Refuse possible leaked file descriptors
10571        if (service != null && service.hasFileDescriptors() == true) {
10572            throw new IllegalArgumentException("File descriptors passed in Intent");
10573        }
10574        synchronized(this) {
10575            return mServices.peekServiceLocked(service, resolvedType);
10576        }
10577    }
10578
10579    public boolean stopServiceToken(ComponentName className, IBinder token,
10580            int startId) {
10581        synchronized(this) {
10582            return mServices.stopServiceTokenLocked(className, token, startId);
10583        }
10584    }
10585
10586    public void setServiceForeground(ComponentName className, IBinder token,
10587            int id, Notification notification, boolean removeNotification) {
10588        synchronized(this) {
10589            mServices.setServiceForegroundLocked(className, token, id, notification,
10590                    removeNotification);
10591        }
10592    }
10593
10594    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10595            String className, int flags) {
10596        boolean result = false;
10597        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10598            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10599                if (ActivityManager.checkUidPermission(
10600                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10601                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10602                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10603                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10604                            + " requests FLAG_SINGLE_USER, but app does not hold "
10605                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10606                    Slog.w(TAG, msg);
10607                    throw new SecurityException(msg);
10608                }
10609                result = true;
10610            }
10611        } else if (componentProcessName == aInfo.packageName) {
10612            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10613        } else if ("system".equals(componentProcessName)) {
10614            result = true;
10615        }
10616        if (DEBUG_MU) {
10617            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10618                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10619        }
10620        return result;
10621    }
10622
10623    public int bindService(IApplicationThread caller, IBinder token,
10624            Intent service, String resolvedType,
10625            IServiceConnection connection, int flags, int userId) {
10626        enforceNotIsolatedCaller("bindService");
10627        // Refuse possible leaked file descriptors
10628        if (service != null && service.hasFileDescriptors() == true) {
10629            throw new IllegalArgumentException("File descriptors passed in Intent");
10630        }
10631
10632        checkValidCaller(Binder.getCallingUid(), userId);
10633
10634        synchronized(this) {
10635            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10636                    connection, flags, userId);
10637        }
10638    }
10639
10640    public boolean unbindService(IServiceConnection connection) {
10641        synchronized (this) {
10642            return mServices.unbindServiceLocked(connection);
10643        }
10644    }
10645
10646    public void publishService(IBinder token, Intent intent, IBinder service) {
10647        // Refuse possible leaked file descriptors
10648        if (intent != null && intent.hasFileDescriptors() == true) {
10649            throw new IllegalArgumentException("File descriptors passed in Intent");
10650        }
10651
10652        synchronized(this) {
10653            if (!(token instanceof ServiceRecord)) {
10654                throw new IllegalArgumentException("Invalid service token");
10655            }
10656            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10657        }
10658    }
10659
10660    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10661        // Refuse possible leaked file descriptors
10662        if (intent != null && intent.hasFileDescriptors() == true) {
10663            throw new IllegalArgumentException("File descriptors passed in Intent");
10664        }
10665
10666        synchronized(this) {
10667            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10668        }
10669    }
10670
10671    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10672        synchronized(this) {
10673            if (!(token instanceof ServiceRecord)) {
10674                throw new IllegalArgumentException("Invalid service token");
10675            }
10676            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10677        }
10678    }
10679
10680    // =========================================================
10681    // BACKUP AND RESTORE
10682    // =========================================================
10683
10684    // Cause the target app to be launched if necessary and its backup agent
10685    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10686    // activity manager to announce its creation.
10687    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10688        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10689        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10690
10691        synchronized(this) {
10692            // !!! TODO: currently no check here that we're already bound
10693            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10694            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10695            synchronized (stats) {
10696                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10697            }
10698
10699            // Backup agent is now in use, its package can't be stopped.
10700            try {
10701                AppGlobals.getPackageManager().setPackageStoppedState(
10702                        app.packageName, false, UserId.getUserId(app.uid));
10703            } catch (RemoteException e) {
10704            } catch (IllegalArgumentException e) {
10705                Slog.w(TAG, "Failed trying to unstop package "
10706                        + app.packageName + ": " + e);
10707            }
10708
10709            BackupRecord r = new BackupRecord(ss, app, backupMode);
10710            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10711                    ? new ComponentName(app.packageName, app.backupAgentName)
10712                    : new ComponentName("android", "FullBackupAgent");
10713            // startProcessLocked() returns existing proc's record if it's already running
10714            ProcessRecord proc = startProcessLocked(app.processName, app,
10715                    false, 0, "backup", hostingName, false, false);
10716            if (proc == null) {
10717                Slog.e(TAG, "Unable to start backup agent process " + r);
10718                return false;
10719            }
10720
10721            r.app = proc;
10722            mBackupTarget = r;
10723            mBackupAppName = app.packageName;
10724
10725            // Try not to kill the process during backup
10726            updateOomAdjLocked(proc);
10727
10728            // If the process is already attached, schedule the creation of the backup agent now.
10729            // If it is not yet live, this will be done when it attaches to the framework.
10730            if (proc.thread != null) {
10731                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10732                try {
10733                    proc.thread.scheduleCreateBackupAgent(app,
10734                            compatibilityInfoForPackageLocked(app), backupMode);
10735                } catch (RemoteException e) {
10736                    // Will time out on the backup manager side
10737                }
10738            } else {
10739                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10740            }
10741            // Invariants: at this point, the target app process exists and the application
10742            // is either already running or in the process of coming up.  mBackupTarget and
10743            // mBackupAppName describe the app, so that when it binds back to the AM we
10744            // know that it's scheduled for a backup-agent operation.
10745        }
10746
10747        return true;
10748    }
10749
10750    // A backup agent has just come up
10751    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10752        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10753                + " = " + agent);
10754
10755        synchronized(this) {
10756            if (!agentPackageName.equals(mBackupAppName)) {
10757                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10758                return;
10759            }
10760        }
10761
10762        long oldIdent = Binder.clearCallingIdentity();
10763        try {
10764            IBackupManager bm = IBackupManager.Stub.asInterface(
10765                    ServiceManager.getService(Context.BACKUP_SERVICE));
10766            bm.agentConnected(agentPackageName, agent);
10767        } catch (RemoteException e) {
10768            // can't happen; the backup manager service is local
10769        } catch (Exception e) {
10770            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10771            e.printStackTrace();
10772        } finally {
10773            Binder.restoreCallingIdentity(oldIdent);
10774        }
10775    }
10776
10777    // done with this agent
10778    public void unbindBackupAgent(ApplicationInfo appInfo) {
10779        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10780        if (appInfo == null) {
10781            Slog.w(TAG, "unbind backup agent for null app");
10782            return;
10783        }
10784
10785        synchronized(this) {
10786            if (mBackupAppName == null) {
10787                Slog.w(TAG, "Unbinding backup agent with no active backup");
10788                return;
10789            }
10790
10791            if (!mBackupAppName.equals(appInfo.packageName)) {
10792                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10793                return;
10794            }
10795
10796            ProcessRecord proc = mBackupTarget.app;
10797            mBackupTarget = null;
10798            mBackupAppName = null;
10799
10800            // Not backing this app up any more; reset its OOM adjustment
10801            updateOomAdjLocked(proc);
10802
10803            // If the app crashed during backup, 'thread' will be null here
10804            if (proc.thread != null) {
10805                try {
10806                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10807                            compatibilityInfoForPackageLocked(appInfo));
10808                } catch (Exception e) {
10809                    Slog.e(TAG, "Exception when unbinding backup agent:");
10810                    e.printStackTrace();
10811                }
10812            }
10813        }
10814    }
10815    // =========================================================
10816    // BROADCASTS
10817    // =========================================================
10818
10819    private final List getStickiesLocked(String action, IntentFilter filter,
10820            List cur) {
10821        final ContentResolver resolver = mContext.getContentResolver();
10822        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10823        if (list == null) {
10824            return cur;
10825        }
10826        int N = list.size();
10827        for (int i=0; i<N; i++) {
10828            Intent intent = list.get(i);
10829            if (filter.match(resolver, intent, true, TAG) >= 0) {
10830                if (cur == null) {
10831                    cur = new ArrayList<Intent>();
10832                }
10833                cur.add(intent);
10834            }
10835        }
10836        return cur;
10837    }
10838
10839    boolean isPendingBroadcastProcessLocked(int pid) {
10840        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10841                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10842    }
10843
10844    void skipPendingBroadcastLocked(int pid) {
10845            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10846            for (BroadcastQueue queue : mBroadcastQueues) {
10847                queue.skipPendingBroadcastLocked(pid);
10848            }
10849    }
10850
10851    // The app just attached; send any pending broadcasts that it should receive
10852    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10853        boolean didSomething = false;
10854        for (BroadcastQueue queue : mBroadcastQueues) {
10855            didSomething |= queue.sendPendingBroadcastsLocked(app);
10856        }
10857        return didSomething;
10858    }
10859
10860    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10861            IIntentReceiver receiver, IntentFilter filter, String permission) {
10862        enforceNotIsolatedCaller("registerReceiver");
10863        int callingUid;
10864        synchronized(this) {
10865            ProcessRecord callerApp = null;
10866            if (caller != null) {
10867                callerApp = getRecordForAppLocked(caller);
10868                if (callerApp == null) {
10869                    throw new SecurityException(
10870                            "Unable to find app for caller " + caller
10871                            + " (pid=" + Binder.getCallingPid()
10872                            + ") when registering receiver " + receiver);
10873                }
10874                if (callerApp.info.uid != Process.SYSTEM_UID &&
10875                        !callerApp.pkgList.contains(callerPackage)) {
10876                    throw new SecurityException("Given caller package " + callerPackage
10877                            + " is not running in process " + callerApp);
10878                }
10879                callingUid = callerApp.info.uid;
10880            } else {
10881                callerPackage = null;
10882                callingUid = Binder.getCallingUid();
10883            }
10884
10885            List allSticky = null;
10886
10887            // Look for any matching sticky broadcasts...
10888            Iterator actions = filter.actionsIterator();
10889            if (actions != null) {
10890                while (actions.hasNext()) {
10891                    String action = (String)actions.next();
10892                    allSticky = getStickiesLocked(action, filter, allSticky);
10893                }
10894            } else {
10895                allSticky = getStickiesLocked(null, filter, allSticky);
10896            }
10897
10898            // The first sticky in the list is returned directly back to
10899            // the client.
10900            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10901
10902            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10903                    + ": " + sticky);
10904
10905            if (receiver == null) {
10906                return sticky;
10907            }
10908
10909            ReceiverList rl
10910                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10911            if (rl == null) {
10912                rl = new ReceiverList(this, callerApp,
10913                        Binder.getCallingPid(),
10914                        Binder.getCallingUid(), receiver);
10915                if (rl.app != null) {
10916                    rl.app.receivers.add(rl);
10917                } else {
10918                    try {
10919                        receiver.asBinder().linkToDeath(rl, 0);
10920                    } catch (RemoteException e) {
10921                        return sticky;
10922                    }
10923                    rl.linkedToDeath = true;
10924                }
10925                mRegisteredReceivers.put(receiver.asBinder(), rl);
10926            }
10927            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10928                    permission, callingUid);
10929            rl.add(bf);
10930            if (!bf.debugCheck()) {
10931                Slog.w(TAG, "==> For Dynamic broadast");
10932            }
10933            mReceiverResolver.addFilter(bf);
10934
10935            // Enqueue broadcasts for all existing stickies that match
10936            // this filter.
10937            if (allSticky != null) {
10938                ArrayList receivers = new ArrayList();
10939                receivers.add(bf);
10940
10941                int N = allSticky.size();
10942                for (int i=0; i<N; i++) {
10943                    Intent intent = (Intent)allSticky.get(i);
10944                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10945                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10946                            null, -1, -1, null, receivers, null, 0, null, null,
10947                            false, true, true, false);
10948                    queue.enqueueParallelBroadcastLocked(r);
10949                    queue.scheduleBroadcastsLocked();
10950                }
10951            }
10952
10953            return sticky;
10954        }
10955    }
10956
10957    public void unregisterReceiver(IIntentReceiver receiver) {
10958        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10959
10960        final long origId = Binder.clearCallingIdentity();
10961        try {
10962            boolean doTrim = false;
10963
10964            synchronized(this) {
10965                ReceiverList rl
10966                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10967                if (rl != null) {
10968                    if (rl.curBroadcast != null) {
10969                        BroadcastRecord r = rl.curBroadcast;
10970                        final boolean doNext = finishReceiverLocked(
10971                                receiver.asBinder(), r.resultCode, r.resultData,
10972                                r.resultExtras, r.resultAbort, true);
10973                        if (doNext) {
10974                            doTrim = true;
10975                            r.queue.processNextBroadcast(false);
10976                        }
10977                    }
10978
10979                    if (rl.app != null) {
10980                        rl.app.receivers.remove(rl);
10981                    }
10982                    removeReceiverLocked(rl);
10983                    if (rl.linkedToDeath) {
10984                        rl.linkedToDeath = false;
10985                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
10986                    }
10987                }
10988            }
10989
10990            // If we actually concluded any broadcasts, we might now be able
10991            // to trim the recipients' apps from our working set
10992            if (doTrim) {
10993                trimApplications();
10994                return;
10995            }
10996
10997        } finally {
10998            Binder.restoreCallingIdentity(origId);
10999        }
11000    }
11001
11002    void removeReceiverLocked(ReceiverList rl) {
11003        mRegisteredReceivers.remove(rl.receiver.asBinder());
11004        int N = rl.size();
11005        for (int i=0; i<N; i++) {
11006            mReceiverResolver.removeFilter(rl.get(i));
11007        }
11008    }
11009
11010    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11011        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11012            ProcessRecord r = mLruProcesses.get(i);
11013            if (r.thread != null) {
11014                try {
11015                    r.thread.dispatchPackageBroadcast(cmd, packages);
11016                } catch (RemoteException ex) {
11017                }
11018            }
11019        }
11020    }
11021
11022    private final int broadcastIntentLocked(ProcessRecord callerApp,
11023            String callerPackage, Intent intent, String resolvedType,
11024            IIntentReceiver resultTo, int resultCode, String resultData,
11025            Bundle map, String requiredPermission,
11026            boolean ordered, boolean sticky, int callingPid, int callingUid,
11027            int userId) {
11028        intent = new Intent(intent);
11029
11030        // By default broadcasts do not go to stopped apps.
11031        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11032
11033        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11034            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11035            + " ordered=" + ordered + " userid=" + userId);
11036        if ((resultTo != null) && !ordered) {
11037            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11038        }
11039
11040        boolean onlySendToCaller = false;
11041
11042        // If the caller is trying to send this broadcast to a different
11043        // user, verify that is allowed.
11044        if (UserId.getUserId(callingUid) != userId) {
11045            if (checkComponentPermission(
11046                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11047                    callingPid, callingUid, -1, true)
11048                    != PackageManager.PERMISSION_GRANTED) {
11049                if (checkComponentPermission(
11050                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11051                        callingPid, callingUid, -1, true)
11052                        == PackageManager.PERMISSION_GRANTED) {
11053                    onlySendToCaller = true;
11054                } else {
11055                    String msg = "Permission Denial: " + intent.getAction()
11056                            + " broadcast from " + callerPackage
11057                            + " asks to send as user " + userId
11058                            + " but is calling from user " + UserId.getUserId(callingUid)
11059                            + "; this requires "
11060                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11061                    Slog.w(TAG, msg);
11062                    throw new SecurityException(msg);
11063                }
11064            }
11065        }
11066
11067        // Handle special intents: if this broadcast is from the package
11068        // manager about a package being removed, we need to remove all of
11069        // its activities from the history stack.
11070        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11071                intent.getAction());
11072        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11073                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11074                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11075                || uidRemoved) {
11076            if (checkComponentPermission(
11077                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11078                    callingPid, callingUid, -1, true)
11079                    == PackageManager.PERMISSION_GRANTED) {
11080                if (uidRemoved) {
11081                    final Bundle intentExtras = intent.getExtras();
11082                    final int uid = intentExtras != null
11083                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11084                    if (uid >= 0) {
11085                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11086                        synchronized (bs) {
11087                            bs.removeUidStatsLocked(uid);
11088                        }
11089                    }
11090                } else {
11091                    // If resources are unvailble just force stop all
11092                    // those packages and flush the attribute cache as well.
11093                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11094                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11095                        if (list != null && (list.length > 0)) {
11096                            for (String pkg : list) {
11097                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11098                            }
11099                            sendPackageBroadcastLocked(
11100                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11101                        }
11102                    } else {
11103                        Uri data = intent.getData();
11104                        String ssp;
11105                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11106                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11107                                forceStopPackageLocked(ssp,
11108                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11109                                        false, userId);
11110                            }
11111                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11112                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11113                                        new String[] {ssp});
11114                            }
11115                        }
11116                    }
11117                }
11118            } else {
11119                String msg = "Permission Denial: " + intent.getAction()
11120                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11121                        + ", uid=" + callingUid + ")"
11122                        + " requires "
11123                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11124                Slog.w(TAG, msg);
11125                throw new SecurityException(msg);
11126            }
11127
11128        // Special case for adding a package: by default turn on compatibility
11129        // mode.
11130        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11131            Uri data = intent.getData();
11132            String ssp;
11133            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11134                mCompatModePackages.handlePackageAddedLocked(ssp,
11135                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11136            }
11137        }
11138
11139        /*
11140         * If this is the time zone changed action, queue up a message that will reset the timezone
11141         * of all currently running processes. This message will get queued up before the broadcast
11142         * happens.
11143         */
11144        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11145            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11146        }
11147
11148        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11149            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11150        }
11151
11152        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11153            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11154            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11155        }
11156
11157        /*
11158         * Prevent non-system code (defined here to be non-persistent
11159         * processes) from sending protected broadcasts.
11160         */
11161        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11162            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11163            callingUid == 0) {
11164            // Always okay.
11165        } else if (callerApp == null || !callerApp.persistent) {
11166            try {
11167                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11168                        intent.getAction())) {
11169                    String msg = "Permission Denial: not allowed to send broadcast "
11170                            + intent.getAction() + " from pid="
11171                            + callingPid + ", uid=" + callingUid;
11172                    Slog.w(TAG, msg);
11173                    throw new SecurityException(msg);
11174                }
11175            } catch (RemoteException e) {
11176                Slog.w(TAG, "Remote exception", e);
11177                return ActivityManager.BROADCAST_SUCCESS;
11178            }
11179        }
11180
11181        // Add to the sticky list if requested.
11182        if (sticky) {
11183            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11184                    callingPid, callingUid)
11185                    != PackageManager.PERMISSION_GRANTED) {
11186                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11187                        + callingPid + ", uid=" + callingUid
11188                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11189                Slog.w(TAG, msg);
11190                throw new SecurityException(msg);
11191            }
11192            if (requiredPermission != null) {
11193                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11194                        + " and enforce permission " + requiredPermission);
11195                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11196            }
11197            if (intent.getComponent() != null) {
11198                throw new SecurityException(
11199                        "Sticky broadcasts can't target a specific component");
11200            }
11201            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11202            if (list == null) {
11203                list = new ArrayList<Intent>();
11204                mStickyBroadcasts.put(intent.getAction(), list);
11205            }
11206            int N = list.size();
11207            int i;
11208            for (i=0; i<N; i++) {
11209                if (intent.filterEquals(list.get(i))) {
11210                    // This sticky already exists, replace it.
11211                    list.set(i, new Intent(intent));
11212                    break;
11213                }
11214            }
11215            if (i >= N) {
11216                list.add(new Intent(intent));
11217            }
11218        }
11219
11220        // Figure out who all will receive this broadcast.
11221        List receivers = null;
11222        List<BroadcastFilter> registeredReceivers = null;
11223        try {
11224            // Need to resolve the intent to interested receivers...
11225            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11226                     == 0) {
11227                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11228                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11229            }
11230            if (intent.getComponent() == null) {
11231                registeredReceivers = mReceiverResolver.queryIntent(intent,
11232                        resolvedType, false, userId);
11233            }
11234        } catch (RemoteException ex) {
11235            // pm is in same process, this will never happen.
11236        }
11237
11238        final boolean replacePending =
11239                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11240
11241        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11242                + " replacePending=" + replacePending);
11243
11244        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11245        if (!ordered && NR > 0) {
11246            // If we are not serializing this broadcast, then send the
11247            // registered receivers separately so they don't wait for the
11248            // components to be launched.
11249            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11250            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11251                    callerPackage, callingPid, callingUid, requiredPermission,
11252                    registeredReceivers, resultTo, resultCode, resultData, map,
11253                    ordered, sticky, false, onlySendToCaller);
11254            if (DEBUG_BROADCAST) Slog.v(
11255                    TAG, "Enqueueing parallel broadcast " + r);
11256            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11257            if (!replaced) {
11258                queue.enqueueParallelBroadcastLocked(r);
11259                queue.scheduleBroadcastsLocked();
11260            }
11261            registeredReceivers = null;
11262            NR = 0;
11263        }
11264
11265        // Merge into one list.
11266        int ir = 0;
11267        if (receivers != null) {
11268            // A special case for PACKAGE_ADDED: do not allow the package
11269            // being added to see this broadcast.  This prevents them from
11270            // using this as a back door to get run as soon as they are
11271            // installed.  Maybe in the future we want to have a special install
11272            // broadcast or such for apps, but we'd like to deliberately make
11273            // this decision.
11274            String skipPackages[] = null;
11275            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11276                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11277                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11278                Uri data = intent.getData();
11279                if (data != null) {
11280                    String pkgName = data.getSchemeSpecificPart();
11281                    if (pkgName != null) {
11282                        skipPackages = new String[] { pkgName };
11283                    }
11284                }
11285            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11286                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11287            }
11288            if (skipPackages != null && (skipPackages.length > 0)) {
11289                for (String skipPackage : skipPackages) {
11290                    if (skipPackage != null) {
11291                        int NT = receivers.size();
11292                        for (int it=0; it<NT; it++) {
11293                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11294                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11295                                receivers.remove(it);
11296                                it--;
11297                                NT--;
11298                            }
11299                        }
11300                    }
11301                }
11302            }
11303
11304            int NT = receivers != null ? receivers.size() : 0;
11305            int it = 0;
11306            ResolveInfo curt = null;
11307            BroadcastFilter curr = null;
11308            while (it < NT && ir < NR) {
11309                if (curt == null) {
11310                    curt = (ResolveInfo)receivers.get(it);
11311                }
11312                if (curr == null) {
11313                    curr = registeredReceivers.get(ir);
11314                }
11315                if (curr.getPriority() >= curt.priority) {
11316                    // Insert this broadcast record into the final list.
11317                    receivers.add(it, curr);
11318                    ir++;
11319                    curr = null;
11320                    it++;
11321                    NT++;
11322                } else {
11323                    // Skip to the next ResolveInfo in the final list.
11324                    it++;
11325                    curt = null;
11326                }
11327            }
11328        }
11329        while (ir < NR) {
11330            if (receivers == null) {
11331                receivers = new ArrayList();
11332            }
11333            receivers.add(registeredReceivers.get(ir));
11334            ir++;
11335        }
11336
11337        if ((receivers != null && receivers.size() > 0)
11338                || resultTo != null) {
11339            BroadcastQueue queue = broadcastQueueForIntent(intent);
11340            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11341                    callerPackage, callingPid, callingUid, requiredPermission,
11342                    receivers, resultTo, resultCode, resultData, map, ordered,
11343                    sticky, false, onlySendToCaller);
11344            if (DEBUG_BROADCAST) Slog.v(
11345                    TAG, "Enqueueing ordered broadcast " + r
11346                    + ": prev had " + queue.mOrderedBroadcasts.size());
11347            if (DEBUG_BROADCAST) {
11348                int seq = r.intent.getIntExtra("seq", -1);
11349                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11350            }
11351            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11352            if (!replaced) {
11353                queue.enqueueOrderedBroadcastLocked(r);
11354                queue.scheduleBroadcastsLocked();
11355            }
11356        }
11357
11358        return ActivityManager.BROADCAST_SUCCESS;
11359    }
11360
11361    final Intent verifyBroadcastLocked(Intent intent) {
11362        // Refuse possible leaked file descriptors
11363        if (intent != null && intent.hasFileDescriptors() == true) {
11364            throw new IllegalArgumentException("File descriptors passed in Intent");
11365        }
11366
11367        int flags = intent.getFlags();
11368
11369        if (!mProcessesReady) {
11370            // if the caller really truly claims to know what they're doing, go
11371            // ahead and allow the broadcast without launching any receivers
11372            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11373                intent = new Intent(intent);
11374                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11375            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11376                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11377                        + " before boot completion");
11378                throw new IllegalStateException("Cannot broadcast before boot completed");
11379            }
11380        }
11381
11382        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11383            throw new IllegalArgumentException(
11384                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11385        }
11386
11387        return intent;
11388    }
11389
11390    public final int broadcastIntent(IApplicationThread caller,
11391            Intent intent, String resolvedType, IIntentReceiver resultTo,
11392            int resultCode, String resultData, Bundle map,
11393            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11394        enforceNotIsolatedCaller("broadcastIntent");
11395        synchronized(this) {
11396            intent = verifyBroadcastLocked(intent);
11397
11398            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11399            final int callingPid = Binder.getCallingPid();
11400            final int callingUid = Binder.getCallingUid();
11401            final long origId = Binder.clearCallingIdentity();
11402            int res = broadcastIntentLocked(callerApp,
11403                    callerApp != null ? callerApp.info.packageName : null,
11404                    intent, resolvedType, resultTo,
11405                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11406                    callingPid, callingUid, userId);
11407            Binder.restoreCallingIdentity(origId);
11408            return res;
11409        }
11410    }
11411
11412    int broadcastIntentInPackage(String packageName, int uid,
11413            Intent intent, String resolvedType, IIntentReceiver resultTo,
11414            int resultCode, String resultData, Bundle map,
11415            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11416        synchronized(this) {
11417            intent = verifyBroadcastLocked(intent);
11418
11419            final long origId = Binder.clearCallingIdentity();
11420            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11421                    resultTo, resultCode, resultData, map, requiredPermission,
11422                    serialized, sticky, -1, uid, userId);
11423            Binder.restoreCallingIdentity(origId);
11424            return res;
11425        }
11426    }
11427
11428    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11429    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11430        // Refuse possible leaked file descriptors
11431        if (intent != null && intent.hasFileDescriptors() == true) {
11432            throw new IllegalArgumentException("File descriptors passed in Intent");
11433        }
11434
11435        synchronized(this) {
11436            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11437                    != PackageManager.PERMISSION_GRANTED) {
11438                String msg = "Permission Denial: unbroadcastIntent() from pid="
11439                        + Binder.getCallingPid()
11440                        + ", uid=" + Binder.getCallingUid()
11441                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11442                Slog.w(TAG, msg);
11443                throw new SecurityException(msg);
11444            }
11445            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11446            if (list != null) {
11447                int N = list.size();
11448                int i;
11449                for (i=0; i<N; i++) {
11450                    if (intent.filterEquals(list.get(i))) {
11451                        list.remove(i);
11452                        break;
11453                    }
11454                }
11455            }
11456        }
11457    }
11458
11459    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11460            String resultData, Bundle resultExtras, boolean resultAbort,
11461            boolean explicit) {
11462        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11463        if (r == null) {
11464            Slog.w(TAG, "finishReceiver called but not found on queue");
11465            return false;
11466        }
11467
11468        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11469                explicit);
11470    }
11471
11472    public void finishReceiver(IBinder who, int resultCode, String resultData,
11473            Bundle resultExtras, boolean resultAbort) {
11474        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11475
11476        // Refuse possible leaked file descriptors
11477        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11478            throw new IllegalArgumentException("File descriptors passed in Bundle");
11479        }
11480
11481        final long origId = Binder.clearCallingIdentity();
11482        try {
11483            boolean doNext = false;
11484            BroadcastRecord r = null;
11485
11486            synchronized(this) {
11487                r = broadcastRecordForReceiverLocked(who);
11488                if (r != null) {
11489                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11490                        resultData, resultExtras, resultAbort, true);
11491                }
11492            }
11493
11494            if (doNext) {
11495                r.queue.processNextBroadcast(false);
11496            }
11497            trimApplications();
11498        } finally {
11499            Binder.restoreCallingIdentity(origId);
11500        }
11501    }
11502
11503    // =========================================================
11504    // INSTRUMENTATION
11505    // =========================================================
11506
11507    public boolean startInstrumentation(ComponentName className,
11508            String profileFile, int flags, Bundle arguments,
11509            IInstrumentationWatcher watcher) {
11510        enforceNotIsolatedCaller("startInstrumentation");
11511        // Refuse possible leaked file descriptors
11512        if (arguments != null && arguments.hasFileDescriptors()) {
11513            throw new IllegalArgumentException("File descriptors passed in Bundle");
11514        }
11515
11516        synchronized(this) {
11517            InstrumentationInfo ii = null;
11518            ApplicationInfo ai = null;
11519            try {
11520                ii = mContext.getPackageManager().getInstrumentationInfo(
11521                    className, STOCK_PM_FLAGS);
11522                ai = mContext.getPackageManager().getApplicationInfo(
11523                        ii.targetPackage, STOCK_PM_FLAGS);
11524            } catch (PackageManager.NameNotFoundException e) {
11525            }
11526            if (ii == null) {
11527                reportStartInstrumentationFailure(watcher, className,
11528                        "Unable to find instrumentation info for: " + className);
11529                return false;
11530            }
11531            if (ai == null) {
11532                reportStartInstrumentationFailure(watcher, className,
11533                        "Unable to find instrumentation target package: " + ii.targetPackage);
11534                return false;
11535            }
11536
11537            int match = mContext.getPackageManager().checkSignatures(
11538                    ii.targetPackage, ii.packageName);
11539            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11540                String msg = "Permission Denial: starting instrumentation "
11541                        + className + " from pid="
11542                        + Binder.getCallingPid()
11543                        + ", uid=" + Binder.getCallingPid()
11544                        + " not allowed because package " + ii.packageName
11545                        + " does not have a signature matching the target "
11546                        + ii.targetPackage;
11547                reportStartInstrumentationFailure(watcher, className, msg);
11548                throw new SecurityException(msg);
11549            }
11550
11551            int userId = UserId.getCallingUserId();
11552            final long origId = Binder.clearCallingIdentity();
11553            // Instrumentation can kill and relaunch even persistent processes
11554            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11555            ProcessRecord app = addAppLocked(ai, false);
11556            app.instrumentationClass = className;
11557            app.instrumentationInfo = ai;
11558            app.instrumentationProfileFile = profileFile;
11559            app.instrumentationArguments = arguments;
11560            app.instrumentationWatcher = watcher;
11561            app.instrumentationResultClass = className;
11562            Binder.restoreCallingIdentity(origId);
11563        }
11564
11565        return true;
11566    }
11567
11568    /**
11569     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11570     * error to the logs, but if somebody is watching, send the report there too.  This enables
11571     * the "am" command to report errors with more information.
11572     *
11573     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11574     * @param cn The component name of the instrumentation.
11575     * @param report The error report.
11576     */
11577    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11578            ComponentName cn, String report) {
11579        Slog.w(TAG, report);
11580        try {
11581            if (watcher != null) {
11582                Bundle results = new Bundle();
11583                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11584                results.putString("Error", report);
11585                watcher.instrumentationStatus(cn, -1, results);
11586            }
11587        } catch (RemoteException e) {
11588            Slog.w(TAG, e);
11589        }
11590    }
11591
11592    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11593        if (app.instrumentationWatcher != null) {
11594            try {
11595                // NOTE:  IInstrumentationWatcher *must* be oneway here
11596                app.instrumentationWatcher.instrumentationFinished(
11597                    app.instrumentationClass,
11598                    resultCode,
11599                    results);
11600            } catch (RemoteException e) {
11601            }
11602        }
11603        app.instrumentationWatcher = null;
11604        app.instrumentationClass = null;
11605        app.instrumentationInfo = null;
11606        app.instrumentationProfileFile = null;
11607        app.instrumentationArguments = null;
11608
11609        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11610    }
11611
11612    public void finishInstrumentation(IApplicationThread target,
11613            int resultCode, Bundle results) {
11614        int userId = UserId.getCallingUserId();
11615        // Refuse possible leaked file descriptors
11616        if (results != null && results.hasFileDescriptors()) {
11617            throw new IllegalArgumentException("File descriptors passed in Intent");
11618        }
11619
11620        synchronized(this) {
11621            ProcessRecord app = getRecordForAppLocked(target);
11622            if (app == null) {
11623                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11624                return;
11625            }
11626            final long origId = Binder.clearCallingIdentity();
11627            finishInstrumentationLocked(app, resultCode, results);
11628            Binder.restoreCallingIdentity(origId);
11629        }
11630    }
11631
11632    // =========================================================
11633    // CONFIGURATION
11634    // =========================================================
11635
11636    public ConfigurationInfo getDeviceConfigurationInfo() {
11637        ConfigurationInfo config = new ConfigurationInfo();
11638        synchronized (this) {
11639            config.reqTouchScreen = mConfiguration.touchscreen;
11640            config.reqKeyboardType = mConfiguration.keyboard;
11641            config.reqNavigation = mConfiguration.navigation;
11642            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11643                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11644                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11645            }
11646            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11647                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11648                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11649            }
11650            config.reqGlEsVersion = GL_ES_VERSION;
11651        }
11652        return config;
11653    }
11654
11655    public Configuration getConfiguration() {
11656        Configuration ci;
11657        synchronized(this) {
11658            ci = new Configuration(mConfiguration);
11659        }
11660        return ci;
11661    }
11662
11663    public void updatePersistentConfiguration(Configuration values) {
11664        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11665                "updateConfiguration()");
11666        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11667                "updateConfiguration()");
11668        if (values == null) {
11669            throw new NullPointerException("Configuration must not be null");
11670        }
11671
11672        synchronized(this) {
11673            final long origId = Binder.clearCallingIdentity();
11674            updateConfigurationLocked(values, null, true, false);
11675            Binder.restoreCallingIdentity(origId);
11676        }
11677    }
11678
11679    public void updateConfiguration(Configuration values) {
11680        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11681                "updateConfiguration()");
11682
11683        synchronized(this) {
11684            if (values == null && mWindowManager != null) {
11685                // sentinel: fetch the current configuration from the window manager
11686                values = mWindowManager.computeNewConfiguration();
11687            }
11688
11689            if (mWindowManager != null) {
11690                mProcessList.applyDisplaySize(mWindowManager);
11691            }
11692
11693            final long origId = Binder.clearCallingIdentity();
11694            if (values != null) {
11695                Settings.System.clearConfiguration(values);
11696            }
11697            updateConfigurationLocked(values, null, false, false);
11698            Binder.restoreCallingIdentity(origId);
11699        }
11700    }
11701
11702    /**
11703     * Do either or both things: (1) change the current configuration, and (2)
11704     * make sure the given activity is running with the (now) current
11705     * configuration.  Returns true if the activity has been left running, or
11706     * false if <var>starting</var> is being destroyed to match the new
11707     * configuration.
11708     * @param persistent TODO
11709     */
11710    boolean updateConfigurationLocked(Configuration values,
11711            ActivityRecord starting, boolean persistent, boolean initLocale) {
11712        // do nothing if we are headless
11713        if (mHeadless) return true;
11714
11715        int changes = 0;
11716
11717        boolean kept = true;
11718
11719        if (values != null) {
11720            Configuration newConfig = new Configuration(mConfiguration);
11721            changes = newConfig.updateFrom(values);
11722            if (changes != 0) {
11723                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11724                    Slog.i(TAG, "Updating configuration to: " + values);
11725                }
11726
11727                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11728
11729                if (values.locale != null && !initLocale) {
11730                    saveLocaleLocked(values.locale,
11731                                     !values.locale.equals(mConfiguration.locale),
11732                                     values.userSetLocale);
11733                }
11734
11735                mConfigurationSeq++;
11736                if (mConfigurationSeq <= 0) {
11737                    mConfigurationSeq = 1;
11738                }
11739                newConfig.seq = mConfigurationSeq;
11740                mConfiguration = newConfig;
11741                Slog.i(TAG, "Config changed: " + newConfig);
11742
11743                final Configuration configCopy = new Configuration(mConfiguration);
11744
11745                // TODO: If our config changes, should we auto dismiss any currently
11746                // showing dialogs?
11747                mShowDialogs = shouldShowDialogs(newConfig);
11748
11749                AttributeCache ac = AttributeCache.instance();
11750                if (ac != null) {
11751                    ac.updateConfiguration(configCopy);
11752                }
11753
11754                // Make sure all resources in our process are updated
11755                // right now, so that anyone who is going to retrieve
11756                // resource values after we return will be sure to get
11757                // the new ones.  This is especially important during
11758                // boot, where the first config change needs to guarantee
11759                // all resources have that config before following boot
11760                // code is executed.
11761                mSystemThread.applyConfigurationToResources(configCopy);
11762
11763                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11764                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11765                    msg.obj = new Configuration(configCopy);
11766                    mHandler.sendMessage(msg);
11767                }
11768
11769                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11770                    ProcessRecord app = mLruProcesses.get(i);
11771                    try {
11772                        if (app.thread != null) {
11773                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11774                                    + app.processName + " new config " + mConfiguration);
11775                            app.thread.scheduleConfigurationChanged(configCopy);
11776                        }
11777                    } catch (Exception e) {
11778                    }
11779                }
11780                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11781                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11782                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11783                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11784                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11785                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11786                    broadcastIntentLocked(null, null,
11787                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11788                            null, null, 0, null, null,
11789                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11790                }
11791            }
11792        }
11793
11794        if (changes != 0 && starting == null) {
11795            // If the configuration changed, and the caller is not already
11796            // in the process of starting an activity, then find the top
11797            // activity to check if its configuration needs to change.
11798            starting = mMainStack.topRunningActivityLocked(null);
11799        }
11800
11801        if (starting != null) {
11802            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11803            // And we need to make sure at this point that all other activities
11804            // are made visible with the correct configuration.
11805            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11806        }
11807
11808        if (values != null && mWindowManager != null) {
11809            mWindowManager.setNewConfiguration(mConfiguration);
11810        }
11811
11812        return kept;
11813    }
11814
11815    /**
11816     * Decide based on the configuration whether we should shouw the ANR,
11817     * crash, etc dialogs.  The idea is that if there is no affordnace to
11818     * press the on-screen buttons, we shouldn't show the dialog.
11819     *
11820     * A thought: SystemUI might also want to get told about this, the Power
11821     * dialog / global actions also might want different behaviors.
11822     */
11823    private static final boolean shouldShowDialogs(Configuration config) {
11824        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11825                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11826    }
11827
11828    /**
11829     * Save the locale.  You must be inside a synchronized (this) block.
11830     */
11831    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11832        if(isDiff) {
11833            SystemProperties.set("user.language", l.getLanguage());
11834            SystemProperties.set("user.region", l.getCountry());
11835        }
11836
11837        if(isPersist) {
11838            SystemProperties.set("persist.sys.language", l.getLanguage());
11839            SystemProperties.set("persist.sys.country", l.getCountry());
11840            SystemProperties.set("persist.sys.localevar", l.getVariant());
11841        }
11842    }
11843
11844    @Override
11845    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11846        ActivityRecord srec = ActivityRecord.forToken(token);
11847        return srec != null && srec.task.affinity != null &&
11848                srec.task.affinity.equals(destAffinity);
11849    }
11850
11851    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11852            Intent resultData) {
11853        ComponentName dest = destIntent.getComponent();
11854
11855        synchronized (this) {
11856            ActivityRecord srec = ActivityRecord.forToken(token);
11857            if (srec == null) {
11858                return false;
11859            }
11860            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11861            final int start = history.indexOf(srec);
11862            if (start < 0) {
11863                // Current activity is not in history stack; do nothing.
11864                return false;
11865            }
11866            int finishTo = start - 1;
11867            ActivityRecord parent = null;
11868            boolean foundParentInTask = false;
11869            if (dest != null) {
11870                TaskRecord tr = srec.task;
11871                for (int i = start - 1; i >= 0; i--) {
11872                    ActivityRecord r = history.get(i);
11873                    if (tr != r.task) {
11874                        // Couldn't find parent in the same task; stop at the one above this.
11875                        // (Root of current task; in-app "home" behavior)
11876                        // Always at least finish the current activity.
11877                        finishTo = Math.min(start - 1, i + 1);
11878                        parent = history.get(finishTo);
11879                        break;
11880                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11881                            r.info.name.equals(dest.getClassName())) {
11882                        finishTo = i;
11883                        parent = r;
11884                        foundParentInTask = true;
11885                        break;
11886                    }
11887                }
11888            }
11889
11890            if (mController != null) {
11891                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11892                if (next != null) {
11893                    // ask watcher if this is allowed
11894                    boolean resumeOK = true;
11895                    try {
11896                        resumeOK = mController.activityResuming(next.packageName);
11897                    } catch (RemoteException e) {
11898                        mController = null;
11899                    }
11900
11901                    if (!resumeOK) {
11902                        return false;
11903                    }
11904                }
11905            }
11906            final long origId = Binder.clearCallingIdentity();
11907            for (int i = start; i > finishTo; i--) {
11908                ActivityRecord r = history.get(i);
11909                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11910                        "navigate-up");
11911                // Only return the supplied result for the first activity finished
11912                resultCode = Activity.RESULT_CANCELED;
11913                resultData = null;
11914            }
11915
11916            if (parent != null && foundParentInTask) {
11917                final int parentLaunchMode = parent.info.launchMode;
11918                final int destIntentFlags = destIntent.getFlags();
11919                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11920                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11921                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11922                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11923                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11924                } else {
11925                    try {
11926                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11927                                destIntent.getComponent(), 0, UserId.getCallingUserId());
11928                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11929                                null, aInfo, parent.appToken, null,
11930                                0, -1, parent.launchedFromUid, 0, null, true, null);
11931                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11932                    } catch (RemoteException e) {
11933                        foundParentInTask = false;
11934                    }
11935                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11936                            resultData, "navigate-up");
11937                }
11938            }
11939            Binder.restoreCallingIdentity(origId);
11940            return foundParentInTask;
11941        }
11942    }
11943
11944    public int getLaunchedFromUid(IBinder activityToken) {
11945        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11946        if (srec == null) {
11947            return -1;
11948        }
11949        return srec.launchedFromUid;
11950    }
11951
11952    // =========================================================
11953    // LIFETIME MANAGEMENT
11954    // =========================================================
11955
11956    // Returns which broadcast queue the app is the current [or imminent] receiver
11957    // on, or 'null' if the app is not an active broadcast recipient.
11958    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11959        BroadcastRecord r = app.curReceiver;
11960        if (r != null) {
11961            return r.queue;
11962        }
11963
11964        // It's not the current receiver, but it might be starting up to become one
11965        synchronized (this) {
11966            for (BroadcastQueue queue : mBroadcastQueues) {
11967                r = queue.mPendingBroadcast;
11968                if (r != null && r.curApp == app) {
11969                    // found it; report which queue it's in
11970                    return queue;
11971                }
11972            }
11973        }
11974
11975        return null;
11976    }
11977
11978    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11979            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11980        if (mAdjSeq == app.adjSeq) {
11981            // This adjustment has already been computed.  If we are calling
11982            // from the top, we may have already computed our adjustment with
11983            // an earlier hidden adjustment that isn't really for us... if
11984            // so, use the new hidden adjustment.
11985            if (!recursed && app.hidden) {
11986                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
11987            }
11988            return app.curRawAdj;
11989        }
11990
11991        if (app.thread == null) {
11992            app.adjSeq = mAdjSeq;
11993            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11994            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
11995        }
11996
11997        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11998        app.adjSource = null;
11999        app.adjTarget = null;
12000        app.empty = false;
12001        app.hidden = false;
12002
12003        final int activitiesSize = app.activities.size();
12004
12005        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12006            // The max adjustment doesn't allow this app to be anything
12007            // below foreground, so it is not worth doing work for it.
12008            app.adjType = "fixed";
12009            app.adjSeq = mAdjSeq;
12010            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12011            app.foregroundActivities = false;
12012            app.keeping = true;
12013            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12014            // System process can do UI, and when they do we want to have
12015            // them trim their memory after the user leaves the UI.  To
12016            // facilitate this, here we need to determine whether or not it
12017            // is currently showing UI.
12018            app.systemNoUi = true;
12019            if (app == TOP_APP) {
12020                app.systemNoUi = false;
12021            } else if (activitiesSize > 0) {
12022                for (int j = 0; j < activitiesSize; j++) {
12023                    final ActivityRecord r = app.activities.get(j);
12024                    if (r.visible) {
12025                        app.systemNoUi = false;
12026                        break;
12027                    }
12028                }
12029            }
12030            return (app.curAdj=app.maxAdj);
12031        }
12032
12033        app.keeping = false;
12034        app.systemNoUi = false;
12035
12036        // Determine the importance of the process, starting with most
12037        // important to least, and assign an appropriate OOM adjustment.
12038        int adj;
12039        int schedGroup;
12040        boolean foregroundActivities = false;
12041        boolean interesting = false;
12042        BroadcastQueue queue;
12043        if (app == TOP_APP) {
12044            // The last app on the list is the foreground app.
12045            adj = ProcessList.FOREGROUND_APP_ADJ;
12046            schedGroup = Process.THREAD_GROUP_DEFAULT;
12047            app.adjType = "top-activity";
12048            foregroundActivities = true;
12049            interesting = true;
12050        } else if (app.instrumentationClass != null) {
12051            // Don't want to kill running instrumentation.
12052            adj = ProcessList.FOREGROUND_APP_ADJ;
12053            schedGroup = Process.THREAD_GROUP_DEFAULT;
12054            app.adjType = "instrumentation";
12055            interesting = true;
12056        } else if ((queue = isReceivingBroadcast(app)) != null) {
12057            // An app that is currently receiving a broadcast also
12058            // counts as being in the foreground for OOM killer purposes.
12059            // It's placed in a sched group based on the nature of the
12060            // broadcast as reflected by which queue it's active in.
12061            adj = ProcessList.FOREGROUND_APP_ADJ;
12062            schedGroup = (queue == mFgBroadcastQueue)
12063                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12064            app.adjType = "broadcast";
12065        } else if (app.executingServices.size() > 0) {
12066            // An app that is currently executing a service callback also
12067            // counts as being in the foreground.
12068            adj = ProcessList.FOREGROUND_APP_ADJ;
12069            schedGroup = Process.THREAD_GROUP_DEFAULT;
12070            app.adjType = "exec-service";
12071        } else if (activitiesSize > 0) {
12072            // This app is in the background with paused activities.
12073            // We inspect activities to potentially upgrade adjustment further below.
12074            adj = hiddenAdj;
12075            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12076            app.hidden = true;
12077            app.adjType = "bg-activities";
12078        } else {
12079            // A very not-needed process.  If this is lower in the lru list,
12080            // we will push it in to the empty bucket.
12081            adj = hiddenAdj;
12082            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12083            app.hidden = true;
12084            app.empty = true;
12085            app.adjType = "bg-empty";
12086        }
12087
12088        boolean hasStoppingActivities = false;
12089
12090        // Examine all activities if not already foreground.
12091        if (!foregroundActivities && activitiesSize > 0) {
12092            for (int j = 0; j < activitiesSize; j++) {
12093                final ActivityRecord r = app.activities.get(j);
12094                if (r.visible) {
12095                    // App has a visible activity; only upgrade adjustment.
12096                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12097                        adj = ProcessList.VISIBLE_APP_ADJ;
12098                        app.adjType = "visible";
12099                    }
12100                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12101                    app.hidden = false;
12102                    foregroundActivities = true;
12103                    break;
12104                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12105                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12106                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12107                        app.adjType = "pausing";
12108                    }
12109                    app.hidden = false;
12110                    foregroundActivities = true;
12111                } else if (r.state == ActivityState.STOPPING) {
12112                    // We will apply the actual adjustment later, because
12113                    // we want to allow this process to immediately go through
12114                    // any memory trimming that is in effect.
12115                    app.hidden = false;
12116                    foregroundActivities = true;
12117                    hasStoppingActivities = true;
12118                }
12119            }
12120        }
12121
12122        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12123            if (app.foregroundServices) {
12124                // The user is aware of this app, so make it visible.
12125                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12126                app.hidden = false;
12127                app.adjType = "foreground-service";
12128                schedGroup = Process.THREAD_GROUP_DEFAULT;
12129            } else if (app.forcingToForeground != null) {
12130                // The user is aware of this app, so make it visible.
12131                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12132                app.hidden = false;
12133                app.adjType = "force-foreground";
12134                app.adjSource = app.forcingToForeground;
12135                schedGroup = Process.THREAD_GROUP_DEFAULT;
12136            }
12137        }
12138
12139        if (app.foregroundServices) {
12140            interesting = true;
12141        }
12142
12143        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12144            // We don't want to kill the current heavy-weight process.
12145            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12146            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12147            app.hidden = false;
12148            app.adjType = "heavy";
12149        }
12150
12151        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12152            // This process is hosting what we currently consider to be the
12153            // home app, so we don't want to let it go into the background.
12154            adj = ProcessList.HOME_APP_ADJ;
12155            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12156            app.hidden = false;
12157            app.adjType = "home";
12158        }
12159
12160        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12161                && app.activities.size() > 0) {
12162            // This was the previous process that showed UI to the user.
12163            // We want to try to keep it around more aggressively, to give
12164            // a good experience around switching between two apps.
12165            adj = ProcessList.PREVIOUS_APP_ADJ;
12166            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12167            app.hidden = false;
12168            app.adjType = "previous";
12169        }
12170
12171        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12172                + " reason=" + app.adjType);
12173
12174        // By default, we use the computed adjustment.  It may be changed if
12175        // there are applications dependent on our services or providers, but
12176        // this gives us a baseline and makes sure we don't get into an
12177        // infinite recursion.
12178        app.adjSeq = mAdjSeq;
12179        app.curRawAdj = app.nonStoppingAdj = adj;
12180
12181        if (mBackupTarget != null && app == mBackupTarget.app) {
12182            // If possible we want to avoid killing apps while they're being backed up
12183            if (adj > ProcessList.BACKUP_APP_ADJ) {
12184                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12185                adj = ProcessList.BACKUP_APP_ADJ;
12186                app.adjType = "backup";
12187                app.hidden = false;
12188            }
12189        }
12190
12191        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12192                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12193            final long now = SystemClock.uptimeMillis();
12194            // This process is more important if the top activity is
12195            // bound to the service.
12196            Iterator<ServiceRecord> jt = app.services.iterator();
12197            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12198                ServiceRecord s = jt.next();
12199                if (s.startRequested) {
12200                    if (app.hasShownUi && app != mHomeProcess) {
12201                        // If this process has shown some UI, let it immediately
12202                        // go to the LRU list because it may be pretty heavy with
12203                        // UI stuff.  We'll tag it with a label just to help
12204                        // debug and understand what is going on.
12205                        if (adj > ProcessList.SERVICE_ADJ) {
12206                            app.adjType = "started-bg-ui-services";
12207                        }
12208                    } else {
12209                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12210                            // This service has seen some activity within
12211                            // recent memory, so we will keep its process ahead
12212                            // of the background processes.
12213                            if (adj > ProcessList.SERVICE_ADJ) {
12214                                adj = ProcessList.SERVICE_ADJ;
12215                                app.adjType = "started-services";
12216                                app.hidden = false;
12217                            }
12218                        }
12219                        // If we have let the service slide into the background
12220                        // state, still have some text describing what it is doing
12221                        // even though the service no longer has an impact.
12222                        if (adj > ProcessList.SERVICE_ADJ) {
12223                            app.adjType = "started-bg-services";
12224                        }
12225                    }
12226                    // Don't kill this process because it is doing work; it
12227                    // has said it is doing work.
12228                    app.keeping = true;
12229                }
12230                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12231                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12232                    Iterator<ArrayList<ConnectionRecord>> kt
12233                            = s.connections.values().iterator();
12234                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12235                        ArrayList<ConnectionRecord> clist = kt.next();
12236                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12237                            // XXX should compute this based on the max of
12238                            // all connected clients.
12239                            ConnectionRecord cr = clist.get(i);
12240                            if (cr.binding.client == app) {
12241                                // Binding to ourself is not interesting.
12242                                continue;
12243                            }
12244                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12245                                ProcessRecord client = cr.binding.client;
12246                                int clientAdj = adj;
12247                                int myHiddenAdj = hiddenAdj;
12248                                if (myHiddenAdj > client.hiddenAdj) {
12249                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12250                                        myHiddenAdj = client.hiddenAdj;
12251                                    } else {
12252                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12253                                    }
12254                                }
12255                                clientAdj = computeOomAdjLocked(
12256                                    client, myHiddenAdj, TOP_APP, true, doingAll);
12257                                String adjType = null;
12258                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12259                                    // Not doing bind OOM management, so treat
12260                                    // this guy more like a started service.
12261                                    if (app.hasShownUi && app != mHomeProcess) {
12262                                        // If this process has shown some UI, let it immediately
12263                                        // go to the LRU list because it may be pretty heavy with
12264                                        // UI stuff.  We'll tag it with a label just to help
12265                                        // debug and understand what is going on.
12266                                        if (adj > clientAdj) {
12267                                            adjType = "bound-bg-ui-services";
12268                                        }
12269                                        app.hidden = false;
12270                                        clientAdj = adj;
12271                                    } else {
12272                                        if (now >= (s.lastActivity
12273                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12274                                            // This service has not seen activity within
12275                                            // recent memory, so allow it to drop to the
12276                                            // LRU list if there is no other reason to keep
12277                                            // it around.  We'll also tag it with a label just
12278                                            // to help debug and undertand what is going on.
12279                                            if (adj > clientAdj) {
12280                                                adjType = "bound-bg-services";
12281                                            }
12282                                            clientAdj = adj;
12283                                        }
12284                                    }
12285                                }
12286                                if (adj > clientAdj) {
12287                                    // If this process has recently shown UI, and
12288                                    // the process that is binding to it is less
12289                                    // important than being visible, then we don't
12290                                    // care about the binding as much as we care
12291                                    // about letting this process get into the LRU
12292                                    // list to be killed and restarted if needed for
12293                                    // memory.
12294                                    if (app.hasShownUi && app != mHomeProcess
12295                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12296                                        adjType = "bound-bg-ui-services";
12297                                    } else {
12298                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12299                                                |Context.BIND_IMPORTANT)) != 0) {
12300                                            adj = clientAdj;
12301                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12302                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12303                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12304                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12305                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12306                                            adj = clientAdj;
12307                                        } else {
12308                                            app.pendingUiClean = true;
12309                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12310                                                adj = ProcessList.VISIBLE_APP_ADJ;
12311                                            }
12312                                        }
12313                                        if (!client.hidden) {
12314                                            app.hidden = false;
12315                                        }
12316                                        if (client.keeping) {
12317                                            app.keeping = true;
12318                                        }
12319                                        adjType = "service";
12320                                    }
12321                                }
12322                                if (adjType != null) {
12323                                    app.adjType = adjType;
12324                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12325                                            .REASON_SERVICE_IN_USE;
12326                                    app.adjSource = cr.binding.client;
12327                                    app.adjSourceOom = clientAdj;
12328                                    app.adjTarget = s.name;
12329                                }
12330                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12331                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12332                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12333                                    }
12334                                }
12335                            }
12336                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12337                                ActivityRecord a = cr.activity;
12338                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12339                                        (a.visible || a.state == ActivityState.RESUMED
12340                                         || a.state == ActivityState.PAUSING)) {
12341                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12342                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12343                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12344                                    }
12345                                    app.hidden = false;
12346                                    app.adjType = "service";
12347                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12348                                            .REASON_SERVICE_IN_USE;
12349                                    app.adjSource = a;
12350                                    app.adjSourceOom = adj;
12351                                    app.adjTarget = s.name;
12352                                }
12353                            }
12354                        }
12355                    }
12356                }
12357            }
12358
12359            // Finally, if this process has active services running in it, we
12360            // would like to avoid killing it unless it would prevent the current
12361            // application from running.  By default we put the process in
12362            // with the rest of the background processes; as we scan through
12363            // its services we may bump it up from there.
12364            if (adj > hiddenAdj) {
12365                adj = hiddenAdj;
12366                app.hidden = false;
12367                app.adjType = "bg-services";
12368            }
12369        }
12370
12371        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12372                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12373            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12374            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12375                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12376                ContentProviderRecord cpr = jt.next();
12377                for (int i = cpr.connections.size()-1;
12378                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12379                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12380                        i--) {
12381                    ContentProviderConnection conn = cpr.connections.get(i);
12382                    ProcessRecord client = conn.client;
12383                    if (client == app) {
12384                        // Being our own client is not interesting.
12385                        continue;
12386                    }
12387                    int myHiddenAdj = hiddenAdj;
12388                    if (myHiddenAdj > client.hiddenAdj) {
12389                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12390                            myHiddenAdj = client.hiddenAdj;
12391                        } else {
12392                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12393                        }
12394                    }
12395                    int clientAdj = computeOomAdjLocked(
12396                        client, myHiddenAdj, TOP_APP, true, doingAll);
12397                    if (adj > clientAdj) {
12398                        if (app.hasShownUi && app != mHomeProcess
12399                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12400                            app.adjType = "bg-ui-provider";
12401                        } else {
12402                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12403                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12404                            app.adjType = "provider";
12405                        }
12406                        if (!client.hidden) {
12407                            app.hidden = false;
12408                        }
12409                        if (client.keeping) {
12410                            app.keeping = true;
12411                        }
12412                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12413                                .REASON_PROVIDER_IN_USE;
12414                        app.adjSource = client;
12415                        app.adjSourceOom = clientAdj;
12416                        app.adjTarget = cpr.name;
12417                    }
12418                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12419                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12420                    }
12421                }
12422                // If the provider has external (non-framework) process
12423                // dependencies, ensure that its adjustment is at least
12424                // FOREGROUND_APP_ADJ.
12425                if (cpr.hasExternalProcessHandles()) {
12426                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12427                        adj = ProcessList.FOREGROUND_APP_ADJ;
12428                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12429                        app.hidden = false;
12430                        app.keeping = true;
12431                        app.adjType = "provider";
12432                        app.adjTarget = cpr.name;
12433                    }
12434                }
12435            }
12436        }
12437
12438        if (adj == ProcessList.SERVICE_ADJ) {
12439            if (doingAll) {
12440                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12441                mNewNumServiceProcs++;
12442            }
12443            if (app.serviceb) {
12444                adj = ProcessList.SERVICE_B_ADJ;
12445            }
12446        } else {
12447            app.serviceb = false;
12448        }
12449
12450        app.nonStoppingAdj = adj;
12451
12452        if (hasStoppingActivities) {
12453            // Only upgrade adjustment.
12454            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12455                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12456                app.adjType = "stopping";
12457            }
12458        }
12459
12460        app.curRawAdj = adj;
12461
12462        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12463        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12464        if (adj > app.maxAdj) {
12465            adj = app.maxAdj;
12466            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12467                schedGroup = Process.THREAD_GROUP_DEFAULT;
12468            }
12469        }
12470        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12471            app.keeping = true;
12472        }
12473
12474        if (app.hasAboveClient) {
12475            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12476            // then we need to drop its adjustment to be lower than the service's
12477            // in order to honor the request.  We want to drop it by one adjustment
12478            // level...  but there is special meaning applied to various levels so
12479            // we will skip some of them.
12480            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12481                // System process will not get dropped, ever
12482            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12483                adj = ProcessList.VISIBLE_APP_ADJ;
12484            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12485                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12486            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12487                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12488            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12489                adj++;
12490            }
12491        }
12492
12493        int importance = app.memImportance;
12494        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12495            app.curAdj = adj;
12496            app.curSchedGroup = schedGroup;
12497            if (!interesting) {
12498                // For this reporting, if there is not something explicitly
12499                // interesting in this process then we will push it to the
12500                // background importance.
12501                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12502            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12503                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12504            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12505                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12506            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12507                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12508            } else if (adj >= ProcessList.SERVICE_ADJ) {
12509                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12510            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12511                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12512            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12513                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12514            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12515                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12516            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12517                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12518            } else {
12519                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12520            }
12521        }
12522
12523        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12524        if (foregroundActivities != app.foregroundActivities) {
12525            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12526        }
12527        if (changes != 0) {
12528            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12529            app.memImportance = importance;
12530            app.foregroundActivities = foregroundActivities;
12531            int i = mPendingProcessChanges.size()-1;
12532            ProcessChangeItem item = null;
12533            while (i >= 0) {
12534                item = mPendingProcessChanges.get(i);
12535                if (item.pid == app.pid) {
12536                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12537                    break;
12538                }
12539                i--;
12540            }
12541            if (i < 0) {
12542                // No existing item in pending changes; need a new one.
12543                final int NA = mAvailProcessChanges.size();
12544                if (NA > 0) {
12545                    item = mAvailProcessChanges.remove(NA-1);
12546                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12547                } else {
12548                    item = new ProcessChangeItem();
12549                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12550                }
12551                item.changes = 0;
12552                item.pid = app.pid;
12553                item.uid = app.info.uid;
12554                if (mPendingProcessChanges.size() == 0) {
12555                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12556                            "*** Enqueueing dispatch processes changed!");
12557                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12558                }
12559                mPendingProcessChanges.add(item);
12560            }
12561            item.changes |= changes;
12562            item.importance = importance;
12563            item.foregroundActivities = foregroundActivities;
12564            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12565                    + Integer.toHexString(System.identityHashCode(item))
12566                    + " " + app.toShortString() + ": changes=" + item.changes
12567                    + " importance=" + item.importance
12568                    + " foreground=" + item.foregroundActivities
12569                    + " type=" + app.adjType + " source=" + app.adjSource
12570                    + " target=" + app.adjTarget);
12571        }
12572
12573        return app.curRawAdj;
12574    }
12575
12576    /**
12577     * Ask a given process to GC right now.
12578     */
12579    final void performAppGcLocked(ProcessRecord app) {
12580        try {
12581            app.lastRequestedGc = SystemClock.uptimeMillis();
12582            if (app.thread != null) {
12583                if (app.reportLowMemory) {
12584                    app.reportLowMemory = false;
12585                    app.thread.scheduleLowMemory();
12586                } else {
12587                    app.thread.processInBackground();
12588                }
12589            }
12590        } catch (Exception e) {
12591            // whatever.
12592        }
12593    }
12594
12595    /**
12596     * Returns true if things are idle enough to perform GCs.
12597     */
12598    private final boolean canGcNowLocked() {
12599        boolean processingBroadcasts = false;
12600        for (BroadcastQueue q : mBroadcastQueues) {
12601            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12602                processingBroadcasts = true;
12603            }
12604        }
12605        return !processingBroadcasts
12606                && (mSleeping || (mMainStack.mResumedActivity != null &&
12607                        mMainStack.mResumedActivity.idle));
12608    }
12609
12610    /**
12611     * Perform GCs on all processes that are waiting for it, but only
12612     * if things are idle.
12613     */
12614    final void performAppGcsLocked() {
12615        final int N = mProcessesToGc.size();
12616        if (N <= 0) {
12617            return;
12618        }
12619        if (canGcNowLocked()) {
12620            while (mProcessesToGc.size() > 0) {
12621                ProcessRecord proc = mProcessesToGc.remove(0);
12622                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12623                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12624                            <= SystemClock.uptimeMillis()) {
12625                        // To avoid spamming the system, we will GC processes one
12626                        // at a time, waiting a few seconds between each.
12627                        performAppGcLocked(proc);
12628                        scheduleAppGcsLocked();
12629                        return;
12630                    } else {
12631                        // It hasn't been long enough since we last GCed this
12632                        // process...  put it in the list to wait for its time.
12633                        addProcessToGcListLocked(proc);
12634                        break;
12635                    }
12636                }
12637            }
12638
12639            scheduleAppGcsLocked();
12640        }
12641    }
12642
12643    /**
12644     * If all looks good, perform GCs on all processes waiting for them.
12645     */
12646    final void performAppGcsIfAppropriateLocked() {
12647        if (canGcNowLocked()) {
12648            performAppGcsLocked();
12649            return;
12650        }
12651        // Still not idle, wait some more.
12652        scheduleAppGcsLocked();
12653    }
12654
12655    /**
12656     * Schedule the execution of all pending app GCs.
12657     */
12658    final void scheduleAppGcsLocked() {
12659        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12660
12661        if (mProcessesToGc.size() > 0) {
12662            // Schedule a GC for the time to the next process.
12663            ProcessRecord proc = mProcessesToGc.get(0);
12664            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12665
12666            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12667            long now = SystemClock.uptimeMillis();
12668            if (when < (now+GC_TIMEOUT)) {
12669                when = now + GC_TIMEOUT;
12670            }
12671            mHandler.sendMessageAtTime(msg, when);
12672        }
12673    }
12674
12675    /**
12676     * Add a process to the array of processes waiting to be GCed.  Keeps the
12677     * list in sorted order by the last GC time.  The process can't already be
12678     * on the list.
12679     */
12680    final void addProcessToGcListLocked(ProcessRecord proc) {
12681        boolean added = false;
12682        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12683            if (mProcessesToGc.get(i).lastRequestedGc <
12684                    proc.lastRequestedGc) {
12685                added = true;
12686                mProcessesToGc.add(i+1, proc);
12687                break;
12688            }
12689        }
12690        if (!added) {
12691            mProcessesToGc.add(0, proc);
12692        }
12693    }
12694
12695    /**
12696     * Set up to ask a process to GC itself.  This will either do it
12697     * immediately, or put it on the list of processes to gc the next
12698     * time things are idle.
12699     */
12700    final void scheduleAppGcLocked(ProcessRecord app) {
12701        long now = SystemClock.uptimeMillis();
12702        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12703            return;
12704        }
12705        if (!mProcessesToGc.contains(app)) {
12706            addProcessToGcListLocked(app);
12707            scheduleAppGcsLocked();
12708        }
12709    }
12710
12711    final void checkExcessivePowerUsageLocked(boolean doKills) {
12712        updateCpuStatsNow();
12713
12714        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12715        boolean doWakeKills = doKills;
12716        boolean doCpuKills = doKills;
12717        if (mLastPowerCheckRealtime == 0) {
12718            doWakeKills = false;
12719        }
12720        if (mLastPowerCheckUptime == 0) {
12721            doCpuKills = false;
12722        }
12723        if (stats.isScreenOn()) {
12724            doWakeKills = false;
12725        }
12726        final long curRealtime = SystemClock.elapsedRealtime();
12727        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12728        final long curUptime = SystemClock.uptimeMillis();
12729        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12730        mLastPowerCheckRealtime = curRealtime;
12731        mLastPowerCheckUptime = curUptime;
12732        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12733            doWakeKills = false;
12734        }
12735        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12736            doCpuKills = false;
12737        }
12738        int i = mLruProcesses.size();
12739        while (i > 0) {
12740            i--;
12741            ProcessRecord app = mLruProcesses.get(i);
12742            if (!app.keeping) {
12743                long wtime;
12744                synchronized (stats) {
12745                    wtime = stats.getProcessWakeTime(app.info.uid,
12746                            app.pid, curRealtime);
12747                }
12748                long wtimeUsed = wtime - app.lastWakeTime;
12749                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12750                if (DEBUG_POWER) {
12751                    StringBuilder sb = new StringBuilder(128);
12752                    sb.append("Wake for ");
12753                    app.toShortString(sb);
12754                    sb.append(": over ");
12755                    TimeUtils.formatDuration(realtimeSince, sb);
12756                    sb.append(" used ");
12757                    TimeUtils.formatDuration(wtimeUsed, sb);
12758                    sb.append(" (");
12759                    sb.append((wtimeUsed*100)/realtimeSince);
12760                    sb.append("%)");
12761                    Slog.i(TAG, sb.toString());
12762                    sb.setLength(0);
12763                    sb.append("CPU for ");
12764                    app.toShortString(sb);
12765                    sb.append(": over ");
12766                    TimeUtils.formatDuration(uptimeSince, sb);
12767                    sb.append(" used ");
12768                    TimeUtils.formatDuration(cputimeUsed, sb);
12769                    sb.append(" (");
12770                    sb.append((cputimeUsed*100)/uptimeSince);
12771                    sb.append("%)");
12772                    Slog.i(TAG, sb.toString());
12773                }
12774                // If a process has held a wake lock for more
12775                // than 50% of the time during this period,
12776                // that sounds bad.  Kill!
12777                if (doWakeKills && realtimeSince > 0
12778                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12779                    synchronized (stats) {
12780                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12781                                realtimeSince, wtimeUsed);
12782                    }
12783                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12784                            + " (pid " + app.pid + "): held " + wtimeUsed
12785                            + " during " + realtimeSince);
12786                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12787                            app.processName, app.setAdj, "excessive wake lock");
12788                    Process.killProcessQuiet(app.pid);
12789                } else if (doCpuKills && uptimeSince > 0
12790                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12791                    synchronized (stats) {
12792                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12793                                uptimeSince, cputimeUsed);
12794                    }
12795                    Slog.w(TAG, "Excessive CPU in " + app.processName
12796                            + " (pid " + app.pid + "): used " + cputimeUsed
12797                            + " during " + uptimeSince);
12798                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12799                            app.processName, app.setAdj, "excessive cpu");
12800                    Process.killProcessQuiet(app.pid);
12801                } else {
12802                    app.lastWakeTime = wtime;
12803                    app.lastCpuTime = app.curCpuTime;
12804                }
12805            }
12806        }
12807    }
12808
12809    private final boolean updateOomAdjLocked(
12810            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
12811        app.hiddenAdj = hiddenAdj;
12812
12813        if (app.thread == null) {
12814            return false;
12815        }
12816
12817        final boolean wasKeeping = app.keeping;
12818
12819        boolean success = true;
12820
12821        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
12822
12823        if (app.curRawAdj != app.setRawAdj) {
12824            if (wasKeeping && !app.keeping) {
12825                // This app is no longer something we want to keep.  Note
12826                // its current wake lock time to later know to kill it if
12827                // it is not behaving well.
12828                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12829                synchronized (stats) {
12830                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12831                            app.pid, SystemClock.elapsedRealtime());
12832                }
12833                app.lastCpuTime = app.curCpuTime;
12834            }
12835
12836            app.setRawAdj = app.curRawAdj;
12837        }
12838
12839        if (app.curAdj != app.setAdj) {
12840            if (Process.setOomAdj(app.pid, app.curAdj)) {
12841                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12842                    TAG, "Set " + app.pid + " " + app.processName +
12843                    " adj " + app.curAdj + ": " + app.adjType);
12844                app.setAdj = app.curAdj;
12845            } else {
12846                success = false;
12847                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12848            }
12849        }
12850        if (app.setSchedGroup != app.curSchedGroup) {
12851            app.setSchedGroup = app.curSchedGroup;
12852            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12853                    "Setting process group of " + app.processName
12854                    + " to " + app.curSchedGroup);
12855            if (app.waitingToKill != null &&
12856                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12857                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12858                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12859                        app.processName, app.setAdj, app.waitingToKill);
12860                app.killedBackground = true;
12861                Process.killProcessQuiet(app.pid);
12862                success = false;
12863            } else {
12864                if (true) {
12865                    long oldId = Binder.clearCallingIdentity();
12866                    try {
12867                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12868                    } catch (Exception e) {
12869                        Slog.w(TAG, "Failed setting process group of " + app.pid
12870                                + " to " + app.curSchedGroup);
12871                        e.printStackTrace();
12872                    } finally {
12873                        Binder.restoreCallingIdentity(oldId);
12874                    }
12875                } else {
12876                    if (app.thread != null) {
12877                        try {
12878                            app.thread.setSchedulingGroup(app.curSchedGroup);
12879                        } catch (RemoteException e) {
12880                        }
12881                    }
12882                }
12883            }
12884        }
12885        return success;
12886    }
12887
12888    private final ActivityRecord resumedAppLocked() {
12889        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12890        if (resumedActivity == null || resumedActivity.app == null) {
12891            resumedActivity = mMainStack.mPausingActivity;
12892            if (resumedActivity == null || resumedActivity.app == null) {
12893                resumedActivity = mMainStack.topRunningActivityLocked(null);
12894            }
12895        }
12896        return resumedActivity;
12897    }
12898
12899    final boolean updateOomAdjLocked(ProcessRecord app) {
12900        final ActivityRecord TOP_ACT = resumedAppLocked();
12901        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12902        int curAdj = app.curAdj;
12903        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12904            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12905
12906        mAdjSeq++;
12907
12908        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
12909        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12910            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12911        if (nowHidden != wasHidden) {
12912            // Changed to/from hidden state, so apps after it in the LRU
12913            // list may also be changed.
12914            updateOomAdjLocked();
12915        }
12916        return success;
12917    }
12918
12919    final void updateOomAdjLocked() {
12920        final ActivityRecord TOP_ACT = resumedAppLocked();
12921        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12922
12923        if (false) {
12924            RuntimeException e = new RuntimeException();
12925            e.fillInStackTrace();
12926            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12927        }
12928
12929        mAdjSeq++;
12930        mNewNumServiceProcs = 0;
12931
12932        // Let's determine how many processes we have running vs.
12933        // how many slots we have for background processes; we may want
12934        // to put multiple processes in a slot of there are enough of
12935        // them.
12936        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
12937        int factor = (mLruProcesses.size()-4)/numSlots;
12938        if (factor < 1) factor = 1;
12939        int step = 0;
12940        int numHidden = 0;
12941        int numTrimming = 0;
12942
12943        // First update the OOM adjustment for each of the
12944        // application processes based on their current state.
12945        int i = mLruProcesses.size();
12946        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12947        while (i > 0) {
12948            i--;
12949            ProcessRecord app = mLruProcesses.get(i);
12950            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12951            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
12952            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
12953                && app.curAdj == curHiddenAdj) {
12954                step++;
12955                if (step >= factor) {
12956                    step = 0;
12957                    curHiddenAdj++;
12958                }
12959            }
12960            if (!app.killedBackground) {
12961                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12962                    numHidden++;
12963                    if (numHidden > mProcessLimit) {
12964                        Slog.i(TAG, "No longer want " + app.processName
12965                                + " (pid " + app.pid + "): hidden #" + numHidden);
12966                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12967                                app.processName, app.setAdj, "too many background");
12968                        app.killedBackground = true;
12969                        Process.killProcessQuiet(app.pid);
12970                    }
12971                }
12972                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
12973                    // If this is an isolated process, and there are no
12974                    // services running in it, then the process is no longer
12975                    // needed.  We agressively kill these because we can by
12976                    // definition not re-use the same process again, and it is
12977                    // good to avoid having whatever code was running in them
12978                    // left sitting around after no longer needed.
12979                    Slog.i(TAG, "Isolated process " + app.processName
12980                            + " (pid " + app.pid + ") no longer needed");
12981                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12982                            app.processName, app.setAdj, "isolated not needed");
12983                    app.killedBackground = true;
12984                    Process.killProcessQuiet(app.pid);
12985                }
12986                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
12987                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
12988                        && !app.killedBackground) {
12989                    numTrimming++;
12990                }
12991            }
12992        }
12993
12994        mNumServiceProcs = mNewNumServiceProcs;
12995
12996        // Now determine the memory trimming level of background processes.
12997        // Unfortunately we need to start at the back of the list to do this
12998        // properly.  We only do this if the number of background apps we
12999        // are managing to keep around is less than half the maximum we desire;
13000        // if we are keeping a good number around, we'll let them use whatever
13001        // memory they want.
13002        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
13003            final int N = mLruProcesses.size();
13004            factor = numTrimming/3;
13005            int minFactor = 2;
13006            if (mHomeProcess != null) minFactor++;
13007            if (mPreviousProcess != null) minFactor++;
13008            if (factor < minFactor) factor = minFactor;
13009            step = 0;
13010            int fgTrimLevel;
13011            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13012                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13013            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13014                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13015            } else {
13016                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13017            }
13018            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13019            for (i=0; i<N; i++) {
13020                ProcessRecord app = mLruProcesses.get(i);
13021                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13022                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13023                        && !app.killedBackground) {
13024                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13025                        try {
13026                            app.thread.scheduleTrimMemory(curLevel);
13027                        } catch (RemoteException e) {
13028                        }
13029                        if (false) {
13030                            // For now we won't do this; our memory trimming seems
13031                            // to be good enough at this point that destroying
13032                            // activities causes more harm than good.
13033                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13034                                    && app != mHomeProcess && app != mPreviousProcess) {
13035                                // Need to do this on its own message because the stack may not
13036                                // be in a consistent state at this point.
13037                                // For these apps we will also finish their activities
13038                                // to help them free memory.
13039                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13040                            }
13041                        }
13042                    }
13043                    app.trimMemoryLevel = curLevel;
13044                    step++;
13045                    if (step >= factor) {
13046                        step = 0;
13047                        switch (curLevel) {
13048                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13049                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13050                                break;
13051                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13052                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13053                                break;
13054                        }
13055                    }
13056                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13057                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13058                            && app.thread != null) {
13059                        try {
13060                            app.thread.scheduleTrimMemory(
13061                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13062                        } catch (RemoteException e) {
13063                        }
13064                    }
13065                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13066                } else {
13067                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13068                            && app.pendingUiClean) {
13069                        // If this application is now in the background and it
13070                        // had done UI, then give it the special trim level to
13071                        // have it free UI resources.
13072                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13073                        if (app.trimMemoryLevel < level && app.thread != null) {
13074                            try {
13075                                app.thread.scheduleTrimMemory(level);
13076                            } catch (RemoteException e) {
13077                            }
13078                        }
13079                        app.pendingUiClean = false;
13080                    }
13081                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13082                        try {
13083                            app.thread.scheduleTrimMemory(fgTrimLevel);
13084                        } catch (RemoteException e) {
13085                        }
13086                    }
13087                    app.trimMemoryLevel = fgTrimLevel;
13088                }
13089            }
13090        } else {
13091            final int N = mLruProcesses.size();
13092            for (i=0; i<N; i++) {
13093                ProcessRecord app = mLruProcesses.get(i);
13094                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13095                        && app.pendingUiClean) {
13096                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13097                            && app.thread != null) {
13098                        try {
13099                            app.thread.scheduleTrimMemory(
13100                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13101                        } catch (RemoteException e) {
13102                        }
13103                    }
13104                    app.pendingUiClean = false;
13105                }
13106                app.trimMemoryLevel = 0;
13107            }
13108        }
13109
13110        if (mAlwaysFinishActivities) {
13111            // Need to do this on its own message because the stack may not
13112            // be in a consistent state at this point.
13113            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13114        }
13115    }
13116
13117    final void trimApplications() {
13118        synchronized (this) {
13119            int i;
13120
13121            // First remove any unused application processes whose package
13122            // has been removed.
13123            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13124                final ProcessRecord app = mRemovedProcesses.get(i);
13125                if (app.activities.size() == 0
13126                        && app.curReceiver == null && app.services.size() == 0) {
13127                    Slog.i(
13128                        TAG, "Exiting empty application process "
13129                        + app.processName + " ("
13130                        + (app.thread != null ? app.thread.asBinder() : null)
13131                        + ")\n");
13132                    if (app.pid > 0 && app.pid != MY_PID) {
13133                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13134                                app.processName, app.setAdj, "empty");
13135                        Process.killProcessQuiet(app.pid);
13136                    } else {
13137                        try {
13138                            app.thread.scheduleExit();
13139                        } catch (Exception e) {
13140                            // Ignore exceptions.
13141                        }
13142                    }
13143                    cleanUpApplicationRecordLocked(app, false, true, -1);
13144                    mRemovedProcesses.remove(i);
13145
13146                    if (app.persistent) {
13147                        if (app.persistent) {
13148                            addAppLocked(app.info, false);
13149                        }
13150                    }
13151                }
13152            }
13153
13154            // Now update the oom adj for all processes.
13155            updateOomAdjLocked();
13156        }
13157    }
13158
13159    /** This method sends the specified signal to each of the persistent apps */
13160    public void signalPersistentProcesses(int sig) throws RemoteException {
13161        if (sig != Process.SIGNAL_USR1) {
13162            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13163        }
13164
13165        synchronized (this) {
13166            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13167                    != PackageManager.PERMISSION_GRANTED) {
13168                throw new SecurityException("Requires permission "
13169                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13170            }
13171
13172            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13173                ProcessRecord r = mLruProcesses.get(i);
13174                if (r.thread != null && r.persistent) {
13175                    Process.sendSignal(r.pid, sig);
13176                }
13177            }
13178        }
13179    }
13180
13181    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13182        if (proc == null || proc == mProfileProc) {
13183            proc = mProfileProc;
13184            path = mProfileFile;
13185            profileType = mProfileType;
13186            clearProfilerLocked();
13187        }
13188        if (proc == null) {
13189            return;
13190        }
13191        try {
13192            proc.thread.profilerControl(false, path, null, profileType);
13193        } catch (RemoteException e) {
13194            throw new IllegalStateException("Process disappeared");
13195        }
13196    }
13197
13198    private void clearProfilerLocked() {
13199        if (mProfileFd != null) {
13200            try {
13201                mProfileFd.close();
13202            } catch (IOException e) {
13203            }
13204        }
13205        mProfileApp = null;
13206        mProfileProc = null;
13207        mProfileFile = null;
13208        mProfileType = 0;
13209        mAutoStopProfiler = false;
13210    }
13211
13212    public boolean profileControl(String process, boolean start,
13213            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13214
13215        try {
13216            synchronized (this) {
13217                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13218                // its own permission.
13219                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13220                        != PackageManager.PERMISSION_GRANTED) {
13221                    throw new SecurityException("Requires permission "
13222                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13223                }
13224
13225                if (start && fd == null) {
13226                    throw new IllegalArgumentException("null fd");
13227                }
13228
13229                ProcessRecord proc = null;
13230                if (process != null) {
13231                    try {
13232                        int pid = Integer.parseInt(process);
13233                        synchronized (mPidsSelfLocked) {
13234                            proc = mPidsSelfLocked.get(pid);
13235                        }
13236                    } catch (NumberFormatException e) {
13237                    }
13238
13239                    if (proc == null) {
13240                        HashMap<String, SparseArray<ProcessRecord>> all
13241                                = mProcessNames.getMap();
13242                        SparseArray<ProcessRecord> procs = all.get(process);
13243                        if (procs != null && procs.size() > 0) {
13244                            proc = procs.valueAt(0);
13245                        }
13246                    }
13247                }
13248
13249                if (start && (proc == null || proc.thread == null)) {
13250                    throw new IllegalArgumentException("Unknown process: " + process);
13251                }
13252
13253                if (start) {
13254                    stopProfilerLocked(null, null, 0);
13255                    setProfileApp(proc.info, proc.processName, path, fd, false);
13256                    mProfileProc = proc;
13257                    mProfileType = profileType;
13258                    try {
13259                        fd = fd.dup();
13260                    } catch (IOException e) {
13261                        fd = null;
13262                    }
13263                    proc.thread.profilerControl(start, path, fd, profileType);
13264                    fd = null;
13265                    mProfileFd = null;
13266                } else {
13267                    stopProfilerLocked(proc, path, profileType);
13268                    if (fd != null) {
13269                        try {
13270                            fd.close();
13271                        } catch (IOException e) {
13272                        }
13273                    }
13274                }
13275
13276                return true;
13277            }
13278        } catch (RemoteException e) {
13279            throw new IllegalStateException("Process disappeared");
13280        } finally {
13281            if (fd != null) {
13282                try {
13283                    fd.close();
13284                } catch (IOException e) {
13285                }
13286            }
13287        }
13288    }
13289
13290    public boolean dumpHeap(String process, boolean managed,
13291            String path, ParcelFileDescriptor fd) throws RemoteException {
13292
13293        try {
13294            synchronized (this) {
13295                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13296                // its own permission (same as profileControl).
13297                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13298                        != PackageManager.PERMISSION_GRANTED) {
13299                    throw new SecurityException("Requires permission "
13300                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13301                }
13302
13303                if (fd == null) {
13304                    throw new IllegalArgumentException("null fd");
13305                }
13306
13307                ProcessRecord proc = null;
13308                try {
13309                    int pid = Integer.parseInt(process);
13310                    synchronized (mPidsSelfLocked) {
13311                        proc = mPidsSelfLocked.get(pid);
13312                    }
13313                } catch (NumberFormatException e) {
13314                }
13315
13316                if (proc == null) {
13317                    HashMap<String, SparseArray<ProcessRecord>> all
13318                            = mProcessNames.getMap();
13319                    SparseArray<ProcessRecord> procs = all.get(process);
13320                    if (procs != null && procs.size() > 0) {
13321                        proc = procs.valueAt(0);
13322                    }
13323                }
13324
13325                if (proc == null || proc.thread == null) {
13326                    throw new IllegalArgumentException("Unknown process: " + process);
13327                }
13328
13329                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13330                if (!isDebuggable) {
13331                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13332                        throw new SecurityException("Process not debuggable: " + proc);
13333                    }
13334                }
13335
13336                proc.thread.dumpHeap(managed, path, fd);
13337                fd = null;
13338                return true;
13339            }
13340        } catch (RemoteException e) {
13341            throw new IllegalStateException("Process disappeared");
13342        } finally {
13343            if (fd != null) {
13344                try {
13345                    fd.close();
13346                } catch (IOException e) {
13347                }
13348            }
13349        }
13350    }
13351
13352    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13353    public void monitor() {
13354        synchronized (this) { }
13355    }
13356
13357    void onCoreSettingsChange(Bundle settings) {
13358        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13359            ProcessRecord processRecord = mLruProcesses.get(i);
13360            try {
13361                if (processRecord.thread != null) {
13362                    processRecord.thread.setCoreSettings(settings);
13363                }
13364            } catch (RemoteException re) {
13365                /* ignore */
13366            }
13367        }
13368    }
13369
13370    // Multi-user methods
13371
13372    public boolean switchUser(int userId) {
13373        final int callingUid = Binder.getCallingUid();
13374        if (callingUid != 0 && callingUid != Process.myUid()) {
13375            Slog.e(TAG, "Trying to switch user from unauthorized app");
13376            return false;
13377        }
13378        if (mCurrentUserId == userId)
13379            return true;
13380
13381        synchronized (this) {
13382            // Check if user is already logged in, otherwise check if user exists first before
13383            // adding to the list of logged in users.
13384            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13385                if (!userExists(userId)) {
13386                    return false;
13387                }
13388                mLoggedInUsers.append(userId, userId);
13389            }
13390
13391            mCurrentUserId = userId;
13392            boolean haveActivities = mMainStack.switchUser(userId);
13393            if (!haveActivities) {
13394                startHomeActivityLocked(userId);
13395            }
13396
13397        }
13398
13399        // Inform of user switch
13400        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13401        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
13402        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13403
13404        return true;
13405    }
13406
13407    @Override
13408    public UserInfo getCurrentUser() throws RemoteException {
13409        final int callingUid = Binder.getCallingUid();
13410        if (callingUid != 0 && callingUid != Process.myUid()) {
13411            Slog.e(TAG, "Trying to get user from unauthorized app");
13412            return null;
13413        }
13414        return getUserManager().getUserInfo(mCurrentUserId);
13415    }
13416
13417    private void onUserRemoved(Intent intent) {
13418        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
13419        if (extraUserId < 1) return;
13420
13421        // Kill all the processes for the user
13422        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13423        synchronized (this) {
13424            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13425            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13426                SparseArray<ProcessRecord> uids = uidMap.getValue();
13427                for (int i = 0; i < uids.size(); i++) {
13428                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
13429                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13430                    }
13431                }
13432            }
13433
13434            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13435                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13436                        false, false, true, true, extraUserId);
13437            }
13438        }
13439    }
13440
13441    private boolean userExists(int userId) {
13442        UserInfo user = getUserManager().getUserInfo(userId);
13443        return user != null;
13444    }
13445
13446    UserManager getUserManager() {
13447        if (mUserManager == null) {
13448            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13449        }
13450        return mUserManager;
13451    }
13452
13453    private void checkValidCaller(int uid, int userId) {
13454        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13455
13456        throw new SecurityException("Caller uid=" + uid
13457                + " is not privileged to communicate with user=" + userId);
13458    }
13459
13460    private int applyUserId(int uid, int userId) {
13461        return UserId.getUid(userId, uid);
13462    }
13463
13464    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13465        if (info == null) return null;
13466        ApplicationInfo newInfo = new ApplicationInfo(info);
13467        newInfo.uid = applyUserId(info.uid, userId);
13468        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13469                + info.packageName;
13470        return newInfo;
13471    }
13472
13473    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13474        if (aInfo == null
13475                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
13476            return aInfo;
13477        }
13478
13479        ActivityInfo info = new ActivityInfo(aInfo);
13480        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13481        return info;
13482    }
13483}
13484