ActivityManagerService.java revision 2a00329c6d55c6cd9166e01963d7410e95d80d21
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.UserHandle;
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 non-hidden/empty process we last found, to help
690     * determine how to distribute hidden/empty processes next time.
691     */
692    int mNumNonHiddenProcs = 0;
693
694    /**
695     * Keep track of the number of hidden procs, to balance oom adj
696     * distribution between those and empty procs.
697     */
698    int mNumHiddenProcs = 0;
699
700    /**
701     * Keep track of the number of service processes we last found, to
702     * determine on the next iteration which should be B services.
703     */
704    int mNumServiceProcs = 0;
705    int mNewNumServiceProcs = 0;
706
707    /**
708     * System monitoring: number of processes that died since the last
709     * N procs were started.
710     */
711    int[] mProcDeaths = new int[20];
712
713    /**
714     * This is set if we had to do a delayed dexopt of an app before launching
715     * it, to increasing the ANR timeouts in that case.
716     */
717    boolean mDidDexOpt;
718
719    String mDebugApp = null;
720    boolean mWaitForDebugger = false;
721    boolean mDebugTransient = false;
722    String mOrigDebugApp = null;
723    boolean mOrigWaitForDebugger = false;
724    boolean mAlwaysFinishActivities = false;
725    IActivityController mController = null;
726    String mProfileApp = null;
727    ProcessRecord mProfileProc = null;
728    String mProfileFile;
729    ParcelFileDescriptor mProfileFd;
730    int mProfileType = 0;
731    boolean mAutoStopProfiler = false;
732    String mOpenGlTraceApp = null;
733
734    static class ProcessChangeItem {
735        static final int CHANGE_ACTIVITIES = 1<<0;
736        static final int CHANGE_IMPORTANCE= 1<<1;
737        int changes;
738        int uid;
739        int pid;
740        int importance;
741        boolean foregroundActivities;
742    }
743
744    final RemoteCallbackList<IProcessObserver> mProcessObservers
745            = new RemoteCallbackList<IProcessObserver>();
746    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
747
748    final ArrayList<ProcessChangeItem> mPendingProcessChanges
749            = new ArrayList<ProcessChangeItem>();
750    final ArrayList<ProcessChangeItem> mAvailProcessChanges
751            = new ArrayList<ProcessChangeItem>();
752
753    /**
754     * Callback of last caller to {@link #requestPss}.
755     */
756    Runnable mRequestPssCallback;
757
758    /**
759     * Remaining processes for which we are waiting results from the last
760     * call to {@link #requestPss}.
761     */
762    final ArrayList<ProcessRecord> mRequestPssList
763            = new ArrayList<ProcessRecord>();
764
765    /**
766     * Runtime statistics collection thread.  This object's lock is used to
767     * protect all related state.
768     */
769    final Thread mProcessStatsThread;
770
771    /**
772     * Used to collect process stats when showing not responding dialog.
773     * Protected by mProcessStatsThread.
774     */
775    final ProcessStats mProcessStats = new ProcessStats(
776            MONITOR_THREAD_CPU_USAGE);
777    final AtomicLong mLastCpuTime = new AtomicLong(0);
778    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
779
780    long mLastWriteTime = 0;
781
782    /**
783     * Set to true after the system has finished booting.
784     */
785    boolean mBooted = false;
786
787    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
788    int mProcessLimitOverride = -1;
789
790    WindowManagerService mWindowManager;
791
792    static ActivityManagerService mSelf;
793    static ActivityThread mSystemThread;
794
795    private int mCurrentUserId;
796    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
797    private UserManager mUserManager;
798
799    private final class AppDeathRecipient implements IBinder.DeathRecipient {
800        final ProcessRecord mApp;
801        final int mPid;
802        final IApplicationThread mAppThread;
803
804        AppDeathRecipient(ProcessRecord app, int pid,
805                IApplicationThread thread) {
806            if (localLOGV) Slog.v(
807                TAG, "New death recipient " + this
808                + " for thread " + thread.asBinder());
809            mApp = app;
810            mPid = pid;
811            mAppThread = thread;
812        }
813
814        public void binderDied() {
815            if (localLOGV) Slog.v(
816                TAG, "Death received in " + this
817                + " for thread " + mAppThread.asBinder());
818            synchronized(ActivityManagerService.this) {
819                appDiedLocked(mApp, mPid, mAppThread);
820            }
821        }
822    }
823
824    static final int SHOW_ERROR_MSG = 1;
825    static final int SHOW_NOT_RESPONDING_MSG = 2;
826    static final int SHOW_FACTORY_ERROR_MSG = 3;
827    static final int UPDATE_CONFIGURATION_MSG = 4;
828    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
829    static final int WAIT_FOR_DEBUGGER_MSG = 6;
830    static final int SERVICE_TIMEOUT_MSG = 12;
831    static final int UPDATE_TIME_ZONE = 13;
832    static final int SHOW_UID_ERROR_MSG = 14;
833    static final int IM_FEELING_LUCKY_MSG = 15;
834    static final int PROC_START_TIMEOUT_MSG = 20;
835    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
836    static final int KILL_APPLICATION_MSG = 22;
837    static final int FINALIZE_PENDING_INTENT_MSG = 23;
838    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
840    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
841    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
842    static final int CLEAR_DNS_CACHE = 28;
843    static final int UPDATE_HTTP_PROXY = 29;
844    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
845    static final int DISPATCH_PROCESSES_CHANGED = 31;
846    static final int DISPATCH_PROCESS_DIED = 32;
847    static final int REPORT_MEM_USAGE = 33;
848
849    static final int FIRST_ACTIVITY_STACK_MSG = 100;
850    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
851    static final int FIRST_COMPAT_MODE_MSG = 300;
852
853    AlertDialog mUidAlert;
854    CompatModeDialog mCompatModeDialog;
855    long mLastMemUsageReportTime = 0;
856
857    final Handler mHandler = new Handler() {
858        //public Handler() {
859        //    if (localLOGV) Slog.v(TAG, "Handler started!");
860        //}
861
862        public void handleMessage(Message msg) {
863            switch (msg.what) {
864            case SHOW_ERROR_MSG: {
865                HashMap data = (HashMap) msg.obj;
866                synchronized (ActivityManagerService.this) {
867                    ProcessRecord proc = (ProcessRecord)data.get("app");
868                    if (proc != null && proc.crashDialog != null) {
869                        Slog.e(TAG, "App already has crash dialog: " + proc);
870                        return;
871                    }
872                    AppErrorResult res = (AppErrorResult) data.get("result");
873                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
874                        Dialog d = new AppErrorDialog(mContext, res, proc);
875                        d.show();
876                        proc.crashDialog = d;
877                    } else {
878                        // The device is asleep, so just pretend that the user
879                        // saw a crash dialog and hit "force quit".
880                        res.set(0);
881                    }
882                }
883
884                ensureBootCompleted();
885            } break;
886            case SHOW_NOT_RESPONDING_MSG: {
887                synchronized (ActivityManagerService.this) {
888                    HashMap data = (HashMap) msg.obj;
889                    ProcessRecord proc = (ProcessRecord)data.get("app");
890                    if (proc != null && proc.anrDialog != null) {
891                        Slog.e(TAG, "App already has anr dialog: " + proc);
892                        return;
893                    }
894
895                    Intent intent = new Intent("android.intent.action.ANR");
896                    if (!mProcessesReady) {
897                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
898                                | Intent.FLAG_RECEIVER_FOREGROUND);
899                    }
900                    broadcastIntentLocked(null, null, intent,
901                            null, null, 0, null, null, null,
902                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
903
904                    if (mShowDialogs) {
905                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
906                                mContext, proc, (ActivityRecord)data.get("activity"));
907                        d.show();
908                        proc.anrDialog = d;
909                    } else {
910                        // Just kill the app if there is no dialog to be shown.
911                        killAppAtUsersRequest(proc, null);
912                    }
913                }
914
915                ensureBootCompleted();
916            } break;
917            case SHOW_STRICT_MODE_VIOLATION_MSG: {
918                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
919                synchronized (ActivityManagerService.this) {
920                    ProcessRecord proc = (ProcessRecord) data.get("app");
921                    if (proc == null) {
922                        Slog.e(TAG, "App not found when showing strict mode dialog.");
923                        break;
924                    }
925                    if (proc.crashDialog != null) {
926                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
927                        return;
928                    }
929                    AppErrorResult res = (AppErrorResult) data.get("result");
930                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
931                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
932                        d.show();
933                        proc.crashDialog = d;
934                    } else {
935                        // The device is asleep, so just pretend that the user
936                        // saw a crash dialog and hit "force quit".
937                        res.set(0);
938                    }
939                }
940                ensureBootCompleted();
941            } break;
942            case SHOW_FACTORY_ERROR_MSG: {
943                Dialog d = new FactoryErrorDialog(
944                    mContext, msg.getData().getCharSequence("msg"));
945                d.show();
946                ensureBootCompleted();
947            } break;
948            case UPDATE_CONFIGURATION_MSG: {
949                final ContentResolver resolver = mContext.getContentResolver();
950                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
951            } break;
952            case GC_BACKGROUND_PROCESSES_MSG: {
953                synchronized (ActivityManagerService.this) {
954                    performAppGcsIfAppropriateLocked();
955                }
956            } break;
957            case WAIT_FOR_DEBUGGER_MSG: {
958                synchronized (ActivityManagerService.this) {
959                    ProcessRecord app = (ProcessRecord)msg.obj;
960                    if (msg.arg1 != 0) {
961                        if (!app.waitedForDebugger) {
962                            Dialog d = new AppWaitingForDebuggerDialog(
963                                    ActivityManagerService.this,
964                                    mContext, app);
965                            app.waitDialog = d;
966                            app.waitedForDebugger = true;
967                            d.show();
968                        }
969                    } else {
970                        if (app.waitDialog != null) {
971                            app.waitDialog.dismiss();
972                            app.waitDialog = null;
973                        }
974                    }
975                }
976            } break;
977            case SERVICE_TIMEOUT_MSG: {
978                if (mDidDexOpt) {
979                    mDidDexOpt = false;
980                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
981                    nmsg.obj = msg.obj;
982                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
983                    return;
984                }
985                mServices.serviceTimeout((ProcessRecord)msg.obj);
986            } break;
987            case UPDATE_TIME_ZONE: {
988                synchronized (ActivityManagerService.this) {
989                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
990                        ProcessRecord r = mLruProcesses.get(i);
991                        if (r.thread != null) {
992                            try {
993                                r.thread.updateTimeZone();
994                            } catch (RemoteException ex) {
995                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
996                            }
997                        }
998                    }
999                }
1000            } break;
1001            case CLEAR_DNS_CACHE: {
1002                synchronized (ActivityManagerService.this) {
1003                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1004                        ProcessRecord r = mLruProcesses.get(i);
1005                        if (r.thread != null) {
1006                            try {
1007                                r.thread.clearDnsCache();
1008                            } catch (RemoteException ex) {
1009                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1010                            }
1011                        }
1012                    }
1013                }
1014            } break;
1015            case UPDATE_HTTP_PROXY: {
1016                ProxyProperties proxy = (ProxyProperties)msg.obj;
1017                String host = "";
1018                String port = "";
1019                String exclList = "";
1020                if (proxy != null) {
1021                    host = proxy.getHost();
1022                    port = Integer.toString(proxy.getPort());
1023                    exclList = proxy.getExclusionList();
1024                }
1025                synchronized (ActivityManagerService.this) {
1026                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1027                        ProcessRecord r = mLruProcesses.get(i);
1028                        if (r.thread != null) {
1029                            try {
1030                                r.thread.setHttpProxy(host, port, exclList);
1031                            } catch (RemoteException ex) {
1032                                Slog.w(TAG, "Failed to update http proxy for: " +
1033                                        r.info.processName);
1034                            }
1035                        }
1036                    }
1037                }
1038            } break;
1039            case SHOW_UID_ERROR_MSG: {
1040                String title = "System UIDs Inconsistent";
1041                String text = "UIDs on the system are inconsistent, you need to wipe your"
1042                        + " data partition or your device will be unstable.";
1043                Log.e(TAG, title + ": " + text);
1044                if (mShowDialogs) {
1045                    // XXX This is a temporary dialog, no need to localize.
1046                    AlertDialog d = new BaseErrorDialog(mContext);
1047                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1048                    d.setCancelable(false);
1049                    d.setTitle(title);
1050                    d.setMessage(text);
1051                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1052                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1053                    mUidAlert = d;
1054                    d.show();
1055                }
1056            } break;
1057            case IM_FEELING_LUCKY_MSG: {
1058                if (mUidAlert != null) {
1059                    mUidAlert.dismiss();
1060                    mUidAlert = null;
1061                }
1062            } break;
1063            case PROC_START_TIMEOUT_MSG: {
1064                if (mDidDexOpt) {
1065                    mDidDexOpt = false;
1066                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1067                    nmsg.obj = msg.obj;
1068                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1069                    return;
1070                }
1071                ProcessRecord app = (ProcessRecord)msg.obj;
1072                synchronized (ActivityManagerService.this) {
1073                    processStartTimedOutLocked(app);
1074                }
1075            } break;
1076            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1077                synchronized (ActivityManagerService.this) {
1078                    doPendingActivityLaunchesLocked(true);
1079                }
1080            } break;
1081            case KILL_APPLICATION_MSG: {
1082                synchronized (ActivityManagerService.this) {
1083                    int uid = msg.arg1;
1084                    boolean restart = (msg.arg2 == 1);
1085                    String pkg = (String) msg.obj;
1086                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1087                            UserHandle.getUserId(uid));
1088                }
1089            } break;
1090            case FINALIZE_PENDING_INTENT_MSG: {
1091                ((PendingIntentRecord)msg.obj).completeFinalize();
1092            } break;
1093            case POST_HEAVY_NOTIFICATION_MSG: {
1094                INotificationManager inm = NotificationManager.getService();
1095                if (inm == null) {
1096                    return;
1097                }
1098
1099                ActivityRecord root = (ActivityRecord)msg.obj;
1100                ProcessRecord process = root.app;
1101                if (process == null) {
1102                    return;
1103                }
1104
1105                try {
1106                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1107                    String text = mContext.getString(R.string.heavy_weight_notification,
1108                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1109                    Notification notification = new Notification();
1110                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1111                    notification.when = 0;
1112                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1113                    notification.tickerText = text;
1114                    notification.defaults = 0; // please be quiet
1115                    notification.sound = null;
1116                    notification.vibrate = null;
1117                    notification.setLatestEventInfo(context, text,
1118                            mContext.getText(R.string.heavy_weight_notification_detail),
1119                            PendingIntent.getActivity(mContext, 0, root.intent,
1120                                    PendingIntent.FLAG_CANCEL_CURRENT));
1121
1122                    try {
1123                        int[] outId = new int[1];
1124                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1125                                notification, outId);
1126                    } catch (RuntimeException e) {
1127                        Slog.w(ActivityManagerService.TAG,
1128                                "Error showing notification for heavy-weight app", e);
1129                    } catch (RemoteException e) {
1130                    }
1131                } catch (NameNotFoundException e) {
1132                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1133                }
1134            } break;
1135            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1136                INotificationManager inm = NotificationManager.getService();
1137                if (inm == null) {
1138                    return;
1139                }
1140                try {
1141                    inm.cancelNotification("android",
1142                            R.string.heavy_weight_notification);
1143                } catch (RuntimeException e) {
1144                    Slog.w(ActivityManagerService.TAG,
1145                            "Error canceling notification for service", e);
1146                } catch (RemoteException e) {
1147                }
1148            } break;
1149            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1150                synchronized (ActivityManagerService.this) {
1151                    checkExcessivePowerUsageLocked(true);
1152                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1153                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1154                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1155                }
1156            } break;
1157            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1158                synchronized (ActivityManagerService.this) {
1159                    ActivityRecord ar = (ActivityRecord)msg.obj;
1160                    if (mCompatModeDialog != null) {
1161                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1162                                ar.info.applicationInfo.packageName)) {
1163                            return;
1164                        }
1165                        mCompatModeDialog.dismiss();
1166                        mCompatModeDialog = null;
1167                    }
1168                    if (ar != null && false) {
1169                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1170                                ar.packageName)) {
1171                            int mode = mCompatModePackages.computeCompatModeLocked(
1172                                    ar.info.applicationInfo);
1173                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1174                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1175                                mCompatModeDialog = new CompatModeDialog(
1176                                        ActivityManagerService.this, mContext,
1177                                        ar.info.applicationInfo);
1178                                mCompatModeDialog.show();
1179                            }
1180                        }
1181                    }
1182                }
1183                break;
1184            }
1185            case DISPATCH_PROCESSES_CHANGED: {
1186                dispatchProcessesChanged();
1187                break;
1188            }
1189            case DISPATCH_PROCESS_DIED: {
1190                final int pid = msg.arg1;
1191                final int uid = msg.arg2;
1192                dispatchProcessDied(pid, uid);
1193                break;
1194            }
1195            case REPORT_MEM_USAGE: {
1196                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1197                if (!isDebuggable) {
1198                    return;
1199                }
1200                synchronized (ActivityManagerService.this) {
1201                    long now = SystemClock.uptimeMillis();
1202                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1203                        // Don't report more than every 5 minutes to somewhat
1204                        // avoid spamming.
1205                        return;
1206                    }
1207                    mLastMemUsageReportTime = now;
1208                }
1209                Thread thread = new Thread() {
1210                    @Override public void run() {
1211                        StringBuilder dropBuilder = new StringBuilder(1024);
1212                        StringBuilder logBuilder = new StringBuilder(1024);
1213                        StringWriter oomSw = new StringWriter();
1214                        PrintWriter oomPw = new PrintWriter(oomSw);
1215                        StringWriter catSw = new StringWriter();
1216                        PrintWriter catPw = new PrintWriter(catSw);
1217                        String[] emptyArgs = new String[] { };
1218                        StringBuilder tag = new StringBuilder(128);
1219                        StringBuilder stack = new StringBuilder(128);
1220                        tag.append("Low on memory -- ");
1221                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1222                                tag, stack);
1223                        dropBuilder.append(stack);
1224                        dropBuilder.append('\n');
1225                        dropBuilder.append('\n');
1226                        String oomString = oomSw.toString();
1227                        dropBuilder.append(oomString);
1228                        dropBuilder.append('\n');
1229                        logBuilder.append(oomString);
1230                        try {
1231                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1232                                    "procrank", });
1233                            final InputStreamReader converter = new InputStreamReader(
1234                                    proc.getInputStream());
1235                            BufferedReader in = new BufferedReader(converter);
1236                            String line;
1237                            while (true) {
1238                                line = in.readLine();
1239                                if (line == null) {
1240                                    break;
1241                                }
1242                                if (line.length() > 0) {
1243                                    logBuilder.append(line);
1244                                    logBuilder.append('\n');
1245                                }
1246                                dropBuilder.append(line);
1247                                dropBuilder.append('\n');
1248                            }
1249                            converter.close();
1250                        } catch (IOException e) {
1251                        }
1252                        synchronized (ActivityManagerService.this) {
1253                            catPw.println();
1254                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1255                            catPw.println();
1256                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1257                                    false, false, null);
1258                            catPw.println();
1259                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1260                        }
1261                        dropBuilder.append(catSw.toString());
1262                        addErrorToDropBox("lowmem", null, "system_server", null,
1263                                null, tag.toString(), dropBuilder.toString(), null, null);
1264                        Slog.i(TAG, logBuilder.toString());
1265                        synchronized (ActivityManagerService.this) {
1266                            long now = SystemClock.uptimeMillis();
1267                            if (mLastMemUsageReportTime < now) {
1268                                mLastMemUsageReportTime = now;
1269                            }
1270                        }
1271                    }
1272                };
1273                thread.start();
1274                break;
1275            }
1276            }
1277        }
1278    };
1279
1280    public static void setSystemProcess() {
1281        try {
1282            ActivityManagerService m = mSelf;
1283
1284            ServiceManager.addService("activity", m, true);
1285            ServiceManager.addService("meminfo", new MemBinder(m));
1286            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1287            ServiceManager.addService("dbinfo", new DbBinder(m));
1288            if (MONITOR_CPU_USAGE) {
1289                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1290            }
1291            ServiceManager.addService("permission", new PermissionController(m));
1292
1293            ApplicationInfo info =
1294                mSelf.mContext.getPackageManager().getApplicationInfo(
1295                            "android", STOCK_PM_FLAGS);
1296            mSystemThread.installSystemApplicationInfo(info);
1297
1298            synchronized (mSelf) {
1299                ProcessRecord app = mSelf.newProcessRecordLocked(
1300                        mSystemThread.getApplicationThread(), info,
1301                        info.processName, false);
1302                app.persistent = true;
1303                app.pid = MY_PID;
1304                app.maxAdj = ProcessList.SYSTEM_ADJ;
1305                mSelf.mProcessNames.put(app.processName, app.uid, app);
1306                synchronized (mSelf.mPidsSelfLocked) {
1307                    mSelf.mPidsSelfLocked.put(app.pid, app);
1308                }
1309                mSelf.updateLruProcessLocked(app, true, true);
1310            }
1311        } catch (PackageManager.NameNotFoundException e) {
1312            throw new RuntimeException(
1313                    "Unable to find android system package", e);
1314        }
1315    }
1316
1317    public void setWindowManager(WindowManagerService wm) {
1318        mWindowManager = wm;
1319    }
1320
1321    public static final Context main(int factoryTest) {
1322        AThread thr = new AThread();
1323        thr.start();
1324
1325        synchronized (thr) {
1326            while (thr.mService == null) {
1327                try {
1328                    thr.wait();
1329                } catch (InterruptedException e) {
1330                }
1331            }
1332        }
1333
1334        ActivityManagerService m = thr.mService;
1335        mSelf = m;
1336        ActivityThread at = ActivityThread.systemMain();
1337        mSystemThread = at;
1338        Context context = at.getSystemContext();
1339        context.setTheme(android.R.style.Theme_Holo);
1340        m.mContext = context;
1341        m.mFactoryTest = factoryTest;
1342        m.mMainStack = new ActivityStack(m, context, true);
1343
1344        m.mBatteryStatsService.publish(context);
1345        m.mUsageStatsService.publish(context);
1346
1347        synchronized (thr) {
1348            thr.mReady = true;
1349            thr.notifyAll();
1350        }
1351
1352        m.startRunning(null, null, null, null);
1353
1354        return context;
1355    }
1356
1357    public static ActivityManagerService self() {
1358        return mSelf;
1359    }
1360
1361    static class AThread extends Thread {
1362        ActivityManagerService mService;
1363        boolean mReady = false;
1364
1365        public AThread() {
1366            super("ActivityManager");
1367        }
1368
1369        public void run() {
1370            Looper.prepare();
1371
1372            android.os.Process.setThreadPriority(
1373                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1374            android.os.Process.setCanSelfBackground(false);
1375
1376            ActivityManagerService m = new ActivityManagerService();
1377
1378            synchronized (this) {
1379                mService = m;
1380                notifyAll();
1381            }
1382
1383            synchronized (this) {
1384                while (!mReady) {
1385                    try {
1386                        wait();
1387                    } catch (InterruptedException e) {
1388                    }
1389                }
1390            }
1391
1392            // For debug builds, log event loop stalls to dropbox for analysis.
1393            if (StrictMode.conditionallyEnableDebugLogging()) {
1394                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1395            }
1396
1397            Looper.loop();
1398        }
1399    }
1400
1401    static class MemBinder extends Binder {
1402        ActivityManagerService mActivityManagerService;
1403        MemBinder(ActivityManagerService activityManagerService) {
1404            mActivityManagerService = activityManagerService;
1405        }
1406
1407        @Override
1408        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1409            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1410                    != PackageManager.PERMISSION_GRANTED) {
1411                pw.println("Permission Denial: can't dump meminfo from from pid="
1412                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1413                        + " without permission " + android.Manifest.permission.DUMP);
1414                return;
1415            }
1416
1417            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1418                    false, null, null, null);
1419        }
1420    }
1421
1422    static class GraphicsBinder extends Binder {
1423        ActivityManagerService mActivityManagerService;
1424        GraphicsBinder(ActivityManagerService activityManagerService) {
1425            mActivityManagerService = activityManagerService;
1426        }
1427
1428        @Override
1429        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1430            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1431                    != PackageManager.PERMISSION_GRANTED) {
1432                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1433                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1434                        + " without permission " + android.Manifest.permission.DUMP);
1435                return;
1436            }
1437
1438            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1439        }
1440    }
1441
1442    static class DbBinder extends Binder {
1443        ActivityManagerService mActivityManagerService;
1444        DbBinder(ActivityManagerService activityManagerService) {
1445            mActivityManagerService = activityManagerService;
1446        }
1447
1448        @Override
1449        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1450            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1451                    != PackageManager.PERMISSION_GRANTED) {
1452                pw.println("Permission Denial: can't dump dbinfo from from pid="
1453                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1454                        + " without permission " + android.Manifest.permission.DUMP);
1455                return;
1456            }
1457
1458            mActivityManagerService.dumpDbInfo(fd, pw, args);
1459        }
1460    }
1461
1462    static class CpuBinder extends Binder {
1463        ActivityManagerService mActivityManagerService;
1464        CpuBinder(ActivityManagerService activityManagerService) {
1465            mActivityManagerService = activityManagerService;
1466        }
1467
1468        @Override
1469        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1470            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1471                    != PackageManager.PERMISSION_GRANTED) {
1472                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1473                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1474                        + " without permission " + android.Manifest.permission.DUMP);
1475                return;
1476            }
1477
1478            synchronized (mActivityManagerService.mProcessStatsThread) {
1479                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1480                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1481                        SystemClock.uptimeMillis()));
1482            }
1483        }
1484    }
1485
1486    private ActivityManagerService() {
1487        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1488
1489        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1490        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1491        mBroadcastQueues[0] = mFgBroadcastQueue;
1492        mBroadcastQueues[1] = mBgBroadcastQueue;
1493
1494        mServices = new ActiveServices(this);
1495
1496        File dataDir = Environment.getDataDirectory();
1497        File systemDir = new File(dataDir, "system");
1498        systemDir.mkdirs();
1499        mBatteryStatsService = new BatteryStatsService(new File(
1500                systemDir, "batterystats.bin").toString());
1501        mBatteryStatsService.getActiveStatistics().readLocked();
1502        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1503        mOnBattery = DEBUG_POWER ? true
1504                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1505        mBatteryStatsService.getActiveStatistics().setCallback(this);
1506
1507        mUsageStatsService = new UsageStatsService(new File(
1508                systemDir, "usagestats").toString());
1509        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1510
1511        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1512            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1513
1514        mConfiguration.setToDefaults();
1515        mConfiguration.locale = Locale.getDefault();
1516        mConfigurationSeq = mConfiguration.seq = 1;
1517        mProcessStats.init();
1518
1519        mCompatModePackages = new CompatModePackages(this, systemDir);
1520
1521        // Add ourself to the Watchdog monitors.
1522        Watchdog.getInstance().addMonitor(this);
1523
1524        mProcessStatsThread = new Thread("ProcessStats") {
1525            public void run() {
1526                while (true) {
1527                    try {
1528                        try {
1529                            synchronized(this) {
1530                                final long now = SystemClock.uptimeMillis();
1531                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1532                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1533                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1534                                //        + ", write delay=" + nextWriteDelay);
1535                                if (nextWriteDelay < nextCpuDelay) {
1536                                    nextCpuDelay = nextWriteDelay;
1537                                }
1538                                if (nextCpuDelay > 0) {
1539                                    mProcessStatsMutexFree.set(true);
1540                                    this.wait(nextCpuDelay);
1541                                }
1542                            }
1543                        } catch (InterruptedException e) {
1544                        }
1545                        updateCpuStatsNow();
1546                    } catch (Exception e) {
1547                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1548                    }
1549                }
1550            }
1551        };
1552        mProcessStatsThread.start();
1553    }
1554
1555    @Override
1556    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1557            throws RemoteException {
1558        if (code == SYSPROPS_TRANSACTION) {
1559            // We need to tell all apps about the system property change.
1560            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1561            synchronized(this) {
1562                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1563                    final int NA = apps.size();
1564                    for (int ia=0; ia<NA; ia++) {
1565                        ProcessRecord app = apps.valueAt(ia);
1566                        if (app.thread != null) {
1567                            procs.add(app.thread.asBinder());
1568                        }
1569                    }
1570                }
1571            }
1572
1573            int N = procs.size();
1574            for (int i=0; i<N; i++) {
1575                Parcel data2 = Parcel.obtain();
1576                try {
1577                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1578                } catch (RemoteException e) {
1579                }
1580                data2.recycle();
1581            }
1582        }
1583        try {
1584            return super.onTransact(code, data, reply, flags);
1585        } catch (RuntimeException e) {
1586            // The activity manager only throws security exceptions, so let's
1587            // log all others.
1588            if (!(e instanceof SecurityException)) {
1589                Slog.e(TAG, "Activity Manager Crash", e);
1590            }
1591            throw e;
1592        }
1593    }
1594
1595    void updateCpuStats() {
1596        final long now = SystemClock.uptimeMillis();
1597        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1598            return;
1599        }
1600        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1601            synchronized (mProcessStatsThread) {
1602                mProcessStatsThread.notify();
1603            }
1604        }
1605    }
1606
1607    void updateCpuStatsNow() {
1608        synchronized (mProcessStatsThread) {
1609            mProcessStatsMutexFree.set(false);
1610            final long now = SystemClock.uptimeMillis();
1611            boolean haveNewCpuStats = false;
1612
1613            if (MONITOR_CPU_USAGE &&
1614                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1615                mLastCpuTime.set(now);
1616                haveNewCpuStats = true;
1617                mProcessStats.update();
1618                //Slog.i(TAG, mProcessStats.printCurrentState());
1619                //Slog.i(TAG, "Total CPU usage: "
1620                //        + mProcessStats.getTotalCpuPercent() + "%");
1621
1622                // Slog the cpu usage if the property is set.
1623                if ("true".equals(SystemProperties.get("events.cpu"))) {
1624                    int user = mProcessStats.getLastUserTime();
1625                    int system = mProcessStats.getLastSystemTime();
1626                    int iowait = mProcessStats.getLastIoWaitTime();
1627                    int irq = mProcessStats.getLastIrqTime();
1628                    int softIrq = mProcessStats.getLastSoftIrqTime();
1629                    int idle = mProcessStats.getLastIdleTime();
1630
1631                    int total = user + system + iowait + irq + softIrq + idle;
1632                    if (total == 0) total = 1;
1633
1634                    EventLog.writeEvent(EventLogTags.CPU,
1635                            ((user+system+iowait+irq+softIrq) * 100) / total,
1636                            (user * 100) / total,
1637                            (system * 100) / total,
1638                            (iowait * 100) / total,
1639                            (irq * 100) / total,
1640                            (softIrq * 100) / total);
1641                }
1642            }
1643
1644            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1645            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1646            synchronized(bstats) {
1647                synchronized(mPidsSelfLocked) {
1648                    if (haveNewCpuStats) {
1649                        if (mOnBattery) {
1650                            int perc = bstats.startAddingCpuLocked();
1651                            int totalUTime = 0;
1652                            int totalSTime = 0;
1653                            final int N = mProcessStats.countStats();
1654                            for (int i=0; i<N; i++) {
1655                                ProcessStats.Stats st = mProcessStats.getStats(i);
1656                                if (!st.working) {
1657                                    continue;
1658                                }
1659                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1660                                int otherUTime = (st.rel_utime*perc)/100;
1661                                int otherSTime = (st.rel_stime*perc)/100;
1662                                totalUTime += otherUTime;
1663                                totalSTime += otherSTime;
1664                                if (pr != null) {
1665                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1666                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1667                                            st.rel_stime-otherSTime);
1668                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1669                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1670                                } else {
1671                                    BatteryStatsImpl.Uid.Proc ps =
1672                                            bstats.getProcessStatsLocked(st.name, st.pid);
1673                                    if (ps != null) {
1674                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1675                                                st.rel_stime-otherSTime);
1676                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1677                                    }
1678                                }
1679                            }
1680                            bstats.finishAddingCpuLocked(perc, totalUTime,
1681                                    totalSTime, cpuSpeedTimes);
1682                        }
1683                    }
1684                }
1685
1686                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1687                    mLastWriteTime = now;
1688                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1689                }
1690            }
1691        }
1692    }
1693
1694    @Override
1695    public void batteryNeedsCpuUpdate() {
1696        updateCpuStatsNow();
1697    }
1698
1699    @Override
1700    public void batteryPowerChanged(boolean onBattery) {
1701        // When plugging in, update the CPU stats first before changing
1702        // the plug state.
1703        updateCpuStatsNow();
1704        synchronized (this) {
1705            synchronized(mPidsSelfLocked) {
1706                mOnBattery = DEBUG_POWER ? true : onBattery;
1707            }
1708        }
1709    }
1710
1711    /**
1712     * Initialize the application bind args. These are passed to each
1713     * process when the bindApplication() IPC is sent to the process. They're
1714     * lazily setup to make sure the services are running when they're asked for.
1715     */
1716    private HashMap<String, IBinder> getCommonServicesLocked() {
1717        if (mAppBindArgs == null) {
1718            mAppBindArgs = new HashMap<String, IBinder>();
1719
1720            // Setup the application init args
1721            mAppBindArgs.put("package", ServiceManager.getService("package"));
1722            mAppBindArgs.put("window", ServiceManager.getService("window"));
1723            mAppBindArgs.put(Context.ALARM_SERVICE,
1724                    ServiceManager.getService(Context.ALARM_SERVICE));
1725        }
1726        return mAppBindArgs;
1727    }
1728
1729    final void setFocusedActivityLocked(ActivityRecord r) {
1730        if (mFocusedActivity != r) {
1731            mFocusedActivity = r;
1732            if (r != null) {
1733                mWindowManager.setFocusedApp(r.appToken, true);
1734            }
1735        }
1736    }
1737
1738    private final void updateLruProcessInternalLocked(ProcessRecord app,
1739            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1740        // put it on the LRU to keep track of when it should be exited.
1741        int lrui = mLruProcesses.indexOf(app);
1742        if (lrui >= 0) mLruProcesses.remove(lrui);
1743
1744        int i = mLruProcesses.size()-1;
1745        int skipTop = 0;
1746
1747        app.lruSeq = mLruSeq;
1748
1749        // compute the new weight for this process.
1750        if (updateActivityTime) {
1751            app.lastActivityTime = SystemClock.uptimeMillis();
1752        }
1753        if (app.activities.size() > 0) {
1754            // If this process has activities, we more strongly want to keep
1755            // it around.
1756            app.lruWeight = app.lastActivityTime;
1757        } else if (app.pubProviders.size() > 0) {
1758            // If this process contains content providers, we want to keep
1759            // it a little more strongly.
1760            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1761            // Also don't let it kick out the first few "real" hidden processes.
1762            skipTop = ProcessList.MIN_HIDDEN_APPS;
1763        } else {
1764            // If this process doesn't have activities, we less strongly
1765            // want to keep it around, and generally want to avoid getting
1766            // in front of any very recently used activities.
1767            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1768            // Also don't let it kick out the first few "real" hidden processes.
1769            skipTop = ProcessList.MIN_HIDDEN_APPS;
1770        }
1771
1772        while (i >= 0) {
1773            ProcessRecord p = mLruProcesses.get(i);
1774            // If this app shouldn't be in front of the first N background
1775            // apps, then skip over that many that are currently hidden.
1776            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1777                skipTop--;
1778            }
1779            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1780                mLruProcesses.add(i+1, app);
1781                break;
1782            }
1783            i--;
1784        }
1785        if (i < 0) {
1786            mLruProcesses.add(0, app);
1787        }
1788
1789        // If the app is currently using a content provider or service,
1790        // bump those processes as well.
1791        if (app.connections.size() > 0) {
1792            for (ConnectionRecord cr : app.connections) {
1793                if (cr.binding != null && cr.binding.service != null
1794                        && cr.binding.service.app != null
1795                        && cr.binding.service.app.lruSeq != mLruSeq) {
1796                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1797                            updateActivityTime, i+1);
1798                }
1799            }
1800        }
1801        for (int j=app.conProviders.size()-1; j>=0; j--) {
1802            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1803            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1804                updateLruProcessInternalLocked(cpr.proc, false,
1805                        updateActivityTime, i+1);
1806            }
1807        }
1808
1809        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1810        if (oomAdj) {
1811            updateOomAdjLocked();
1812        }
1813    }
1814
1815    final void updateLruProcessLocked(ProcessRecord app,
1816            boolean oomAdj, boolean updateActivityTime) {
1817        mLruSeq++;
1818        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1819    }
1820
1821    final ProcessRecord getProcessRecordLocked(
1822            String processName, int uid) {
1823        if (uid == Process.SYSTEM_UID) {
1824            // The system gets to run in any process.  If there are multiple
1825            // processes with the same uid, just pick the first (this
1826            // should never happen).
1827            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1828                    processName);
1829            if (procs == null) return null;
1830            final int N = procs.size();
1831            for (int i = 0; i < N; i++) {
1832                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1833            }
1834        }
1835        ProcessRecord proc = mProcessNames.get(processName, uid);
1836        return proc;
1837    }
1838
1839    void ensurePackageDexOpt(String packageName) {
1840        IPackageManager pm = AppGlobals.getPackageManager();
1841        try {
1842            if (pm.performDexOpt(packageName)) {
1843                mDidDexOpt = true;
1844            }
1845        } catch (RemoteException e) {
1846        }
1847    }
1848
1849    boolean isNextTransitionForward() {
1850        int transit = mWindowManager.getPendingAppTransition();
1851        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1852                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1853                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1854    }
1855
1856    final ProcessRecord startProcessLocked(String processName,
1857            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1858            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1859            boolean isolated) {
1860        ProcessRecord app;
1861        if (!isolated) {
1862            app = getProcessRecordLocked(processName, info.uid);
1863        } else {
1864            // If this is an isolated process, it can't re-use an existing process.
1865            app = null;
1866        }
1867        // We don't have to do anything more if:
1868        // (1) There is an existing application record; and
1869        // (2) The caller doesn't think it is dead, OR there is no thread
1870        //     object attached to it so we know it couldn't have crashed; and
1871        // (3) There is a pid assigned to it, so it is either starting or
1872        //     already running.
1873        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1874                + " app=" + app + " knownToBeDead=" + knownToBeDead
1875                + " thread=" + (app != null ? app.thread : null)
1876                + " pid=" + (app != null ? app.pid : -1));
1877        if (app != null && app.pid > 0) {
1878            if (!knownToBeDead || app.thread == null) {
1879                // We already have the app running, or are waiting for it to
1880                // come up (we have a pid but not yet its thread), so keep it.
1881                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1882                // If this is a new package in the process, add the package to the list
1883                app.addPackage(info.packageName);
1884                return app;
1885            } else {
1886                // An application record is attached to a previous process,
1887                // clean it up now.
1888                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1889                handleAppDiedLocked(app, true, true);
1890            }
1891        }
1892
1893        String hostingNameStr = hostingName != null
1894                ? hostingName.flattenToShortString() : null;
1895
1896        if (!isolated) {
1897            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1898                // If we are in the background, then check to see if this process
1899                // is bad.  If so, we will just silently fail.
1900                if (mBadProcesses.get(info.processName, info.uid) != null) {
1901                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1902                            + "/" + info.processName);
1903                    return null;
1904                }
1905            } else {
1906                // When the user is explicitly starting a process, then clear its
1907                // crash count so that we won't make it bad until they see at
1908                // least one crash dialog again, and make the process good again
1909                // if it had been bad.
1910                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1911                        + "/" + info.processName);
1912                mProcessCrashTimes.remove(info.processName, info.uid);
1913                if (mBadProcesses.get(info.processName, info.uid) != null) {
1914                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1915                            info.processName);
1916                    mBadProcesses.remove(info.processName, info.uid);
1917                    if (app != null) {
1918                        app.bad = false;
1919                    }
1920                }
1921            }
1922        }
1923
1924        if (app == null) {
1925            app = newProcessRecordLocked(null, info, processName, isolated);
1926            if (app == null) {
1927                Slog.w(TAG, "Failed making new process record for "
1928                        + processName + "/" + info.uid + " isolated=" + isolated);
1929                return null;
1930            }
1931            mProcessNames.put(processName, app.uid, app);
1932            if (isolated) {
1933                mIsolatedProcesses.put(app.uid, app);
1934            }
1935        } else {
1936            // If this is a new package in the process, add the package to the list
1937            app.addPackage(info.packageName);
1938        }
1939
1940        // If the system is not ready yet, then hold off on starting this
1941        // process until it is.
1942        if (!mProcessesReady
1943                && !isAllowedWhileBooting(info)
1944                && !allowWhileBooting) {
1945            if (!mProcessesOnHold.contains(app)) {
1946                mProcessesOnHold.add(app);
1947            }
1948            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1949            return app;
1950        }
1951
1952        startProcessLocked(app, hostingType, hostingNameStr);
1953        return (app.pid != 0) ? app : null;
1954    }
1955
1956    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1957        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1958    }
1959
1960    private final void startProcessLocked(ProcessRecord app,
1961            String hostingType, String hostingNameStr) {
1962        if (app.pid > 0 && app.pid != MY_PID) {
1963            synchronized (mPidsSelfLocked) {
1964                mPidsSelfLocked.remove(app.pid);
1965                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1966            }
1967            app.setPid(0);
1968        }
1969
1970        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1971                "startProcessLocked removing on hold: " + app);
1972        mProcessesOnHold.remove(app);
1973
1974        updateCpuStats();
1975
1976        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1977        mProcDeaths[0] = 0;
1978
1979        try {
1980            int uid = app.uid;
1981
1982            int[] gids = null;
1983            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1984            if (!app.isolated) {
1985                try {
1986                    final PackageManager pm = mContext.getPackageManager();
1987                    gids = pm.getPackageGids(app.info.packageName);
1988                    if (pm.checkPermission(
1989                            android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName)
1990                            == PERMISSION_GRANTED) {
1991                        if (Environment.isExternalStorageEmulated()) {
1992                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1993                        } else {
1994                            mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
1995                        }
1996                    }
1997                } catch (PackageManager.NameNotFoundException e) {
1998                    Slog.w(TAG, "Unable to retrieve gids", e);
1999                }
2000            }
2001            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2002                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2003                        && mTopComponent != null
2004                        && app.processName.equals(mTopComponent.getPackageName())) {
2005                    uid = 0;
2006                }
2007                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2008                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2009                    uid = 0;
2010                }
2011            }
2012            int debugFlags = 0;
2013            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2014                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2015                // Also turn on CheckJNI for debuggable apps. It's quite
2016                // awkward to turn on otherwise.
2017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2018            }
2019            // Run the app in safe mode if its manifest requests so or the
2020            // system is booted in safe mode.
2021            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2022                Zygote.systemInSafeMode == true) {
2023                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2024            }
2025            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2026                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2027            }
2028            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2029                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2030            }
2031            if ("1".equals(SystemProperties.get("debug.assert"))) {
2032                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2033            }
2034
2035            // Start the process.  It will either succeed and return a result containing
2036            // the PID of the new process, or else throw a RuntimeException.
2037            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2038                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2039                    app.info.targetSdkVersion, null, null);
2040
2041            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2042            synchronized (bs) {
2043                if (bs.isOnBattery()) {
2044                    app.batteryStats.incStartsLocked();
2045                }
2046            }
2047
2048            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2049                    app.processName, hostingType,
2050                    hostingNameStr != null ? hostingNameStr : "");
2051
2052            if (app.persistent) {
2053                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2054            }
2055
2056            StringBuilder buf = mStringBuilder;
2057            buf.setLength(0);
2058            buf.append("Start proc ");
2059            buf.append(app.processName);
2060            buf.append(" for ");
2061            buf.append(hostingType);
2062            if (hostingNameStr != null) {
2063                buf.append(" ");
2064                buf.append(hostingNameStr);
2065            }
2066            buf.append(": pid=");
2067            buf.append(startResult.pid);
2068            buf.append(" uid=");
2069            buf.append(uid);
2070            buf.append(" gids={");
2071            if (gids != null) {
2072                for (int gi=0; gi<gids.length; gi++) {
2073                    if (gi != 0) buf.append(", ");
2074                    buf.append(gids[gi]);
2075
2076                }
2077            }
2078            buf.append("}");
2079            Slog.i(TAG, buf.toString());
2080            app.setPid(startResult.pid);
2081            app.usingWrapper = startResult.usingWrapper;
2082            app.removed = false;
2083            synchronized (mPidsSelfLocked) {
2084                this.mPidsSelfLocked.put(startResult.pid, app);
2085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2086                msg.obj = app;
2087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2089            }
2090        } catch (RuntimeException e) {
2091            // XXX do better error recovery.
2092            app.setPid(0);
2093            Slog.e(TAG, "Failure starting process " + app.processName, e);
2094        }
2095    }
2096
2097    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2098        if (resumed) {
2099            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2100        } else {
2101            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2102        }
2103    }
2104
2105    boolean startHomeActivityLocked(int userId) {
2106        if (mHeadless) {
2107            // Added because none of the other calls to ensureBootCompleted seem to fire
2108            // when running headless.
2109            ensureBootCompleted();
2110            return false;
2111        }
2112
2113        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2114                && mTopAction == null) {
2115            // We are running in factory test mode, but unable to find
2116            // the factory test app, so just sit around displaying the
2117            // error message and don't try to start anything.
2118            return false;
2119        }
2120        Intent intent = new Intent(
2121            mTopAction,
2122            mTopData != null ? Uri.parse(mTopData) : null);
2123        intent.setComponent(mTopComponent);
2124        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2125            intent.addCategory(Intent.CATEGORY_HOME);
2126        }
2127        ActivityInfo aInfo =
2128            intent.resolveActivityInfo(mContext.getPackageManager(),
2129                    STOCK_PM_FLAGS);
2130        if (aInfo != null) {
2131            intent.setComponent(new ComponentName(
2132                    aInfo.applicationInfo.packageName, aInfo.name));
2133            // Don't do this if the home app is currently being
2134            // instrumented.
2135            aInfo = new ActivityInfo(aInfo);
2136            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2137            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2138                    aInfo.applicationInfo.uid);
2139            if (app == null || app.instrumentationClass == null) {
2140                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2141                mMainStack.startActivityLocked(null, intent, null, aInfo,
2142                        null, null, 0, 0, 0, 0, null, false, null);
2143            }
2144        }
2145
2146        return true;
2147    }
2148
2149    /**
2150     * Starts the "new version setup screen" if appropriate.
2151     */
2152    void startSetupActivityLocked() {
2153        // Only do this once per boot.
2154        if (mCheckedForSetup) {
2155            return;
2156        }
2157
2158        // We will show this screen if the current one is a different
2159        // version than the last one shown, and we are not running in
2160        // low-level factory test mode.
2161        final ContentResolver resolver = mContext.getContentResolver();
2162        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2163                Settings.Secure.getInt(resolver,
2164                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2165            mCheckedForSetup = true;
2166
2167            // See if we should be showing the platform update setup UI.
2168            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2169            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2170                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2171
2172            // We don't allow third party apps to replace this.
2173            ResolveInfo ri = null;
2174            for (int i=0; ris != null && i<ris.size(); i++) {
2175                if ((ris.get(i).activityInfo.applicationInfo.flags
2176                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2177                    ri = ris.get(i);
2178                    break;
2179                }
2180            }
2181
2182            if (ri != null) {
2183                String vers = ri.activityInfo.metaData != null
2184                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2185                        : null;
2186                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2187                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2188                            Intent.METADATA_SETUP_VERSION);
2189                }
2190                String lastVers = Settings.Secure.getString(
2191                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2192                if (vers != null && !vers.equals(lastVers)) {
2193                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2194                    intent.setComponent(new ComponentName(
2195                            ri.activityInfo.packageName, ri.activityInfo.name));
2196                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2197                            null, null, 0, 0, 0, 0, null, false, null);
2198                }
2199            }
2200        }
2201    }
2202
2203    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2204        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2205    }
2206
2207    void enforceNotIsolatedCaller(String caller) {
2208        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2209            throw new SecurityException("Isolated process not allowed to call " + caller);
2210        }
2211    }
2212
2213    public int getFrontActivityScreenCompatMode() {
2214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2215        synchronized (this) {
2216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2217        }
2218    }
2219
2220    public void setFrontActivityScreenCompatMode(int mode) {
2221        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2222                "setFrontActivityScreenCompatMode");
2223        synchronized (this) {
2224            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2225        }
2226    }
2227
2228    public int getPackageScreenCompatMode(String packageName) {
2229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2230        synchronized (this) {
2231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2232        }
2233    }
2234
2235    public void setPackageScreenCompatMode(String packageName, int mode) {
2236        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2237                "setPackageScreenCompatMode");
2238        synchronized (this) {
2239            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2240        }
2241    }
2242
2243    public boolean getPackageAskScreenCompat(String packageName) {
2244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2245        synchronized (this) {
2246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2247        }
2248    }
2249
2250    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2251        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2252                "setPackageAskScreenCompat");
2253        synchronized (this) {
2254            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2255        }
2256    }
2257
2258    void reportResumedActivityLocked(ActivityRecord r) {
2259        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2260        updateUsageStats(r, true);
2261    }
2262
2263    private void dispatchProcessesChanged() {
2264        int N;
2265        synchronized (this) {
2266            N = mPendingProcessChanges.size();
2267            if (mActiveProcessChanges.length < N) {
2268                mActiveProcessChanges = new ProcessChangeItem[N];
2269            }
2270            mPendingProcessChanges.toArray(mActiveProcessChanges);
2271            mAvailProcessChanges.addAll(mPendingProcessChanges);
2272            mPendingProcessChanges.clear();
2273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2274        }
2275        int i = mProcessObservers.beginBroadcast();
2276        while (i > 0) {
2277            i--;
2278            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2279            if (observer != null) {
2280                try {
2281                    for (int j=0; j<N; j++) {
2282                        ProcessChangeItem item = mActiveProcessChanges[j];
2283                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2285                                    + item.pid + " uid=" + item.uid + ": "
2286                                    + item.foregroundActivities);
2287                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2288                                    item.foregroundActivities);
2289                        }
2290                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2291                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2292                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2293                            observer.onImportanceChanged(item.pid, item.uid,
2294                                    item.importance);
2295                        }
2296                    }
2297                } catch (RemoteException e) {
2298                }
2299            }
2300        }
2301        mProcessObservers.finishBroadcast();
2302    }
2303
2304    private void dispatchProcessDied(int pid, int uid) {
2305        int i = mProcessObservers.beginBroadcast();
2306        while (i > 0) {
2307            i--;
2308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2309            if (observer != null) {
2310                try {
2311                    observer.onProcessDied(pid, uid);
2312                } catch (RemoteException e) {
2313                }
2314            }
2315        }
2316        mProcessObservers.finishBroadcast();
2317    }
2318
2319    final void doPendingActivityLaunchesLocked(boolean doResume) {
2320        final int N = mPendingActivityLaunches.size();
2321        if (N <= 0) {
2322            return;
2323        }
2324        for (int i=0; i<N; i++) {
2325            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2326            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2327                    pal.startFlags, doResume && i == (N-1), null);
2328        }
2329        mPendingActivityLaunches.clear();
2330    }
2331
2332    public final int startActivity(IApplicationThread caller,
2333            Intent intent, String resolvedType, IBinder resultTo,
2334            String resultWho, int requestCode, int startFlags,
2335            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2336        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2337                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2338    }
2339
2340    public final int startActivityAsUser(IApplicationThread caller,
2341            Intent intent, String resolvedType, IBinder resultTo,
2342            String resultWho, int requestCode, int startFlags,
2343            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2344        enforceNotIsolatedCaller("startActivity");
2345        if (userId != UserHandle.getCallingUserId()) {
2346            // Requesting a different user, make sure that they have the permission
2347            if (checkComponentPermission(
2348                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2349                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2350                    == PackageManager.PERMISSION_GRANTED) {
2351                // Translate to the current user id, if caller wasn't aware
2352                if (userId == UserHandle.USER_CURRENT) {
2353                    userId = mCurrentUserId;
2354                }
2355            } else {
2356                String msg = "Permission Denial: "
2357                        + "Request to startActivity as user " + userId
2358                        + " but is calling from user " + UserHandle.getCallingUserId()
2359                        + "; this requires "
2360                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2361                Slog.w(TAG, msg);
2362                throw new SecurityException(msg);
2363            }
2364        } else {
2365            if (intent.getCategories() != null
2366                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2367                // Requesting home, set the identity to the current user
2368                // HACK!
2369                userId = mCurrentUserId;
2370            } else {
2371                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2372                // the current user's userId
2373                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2374                    userId = 0;
2375                } else {
2376                    userId = Binder.getOrigCallingUser();
2377                }
2378            }
2379        }
2380        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2381                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2382                null, null, options, userId);
2383    }
2384
2385    public final WaitResult startActivityAndWait(IApplicationThread caller,
2386            Intent intent, String resolvedType, IBinder resultTo,
2387            String resultWho, int requestCode, int startFlags, String profileFile,
2388            ParcelFileDescriptor profileFd, Bundle options) {
2389        enforceNotIsolatedCaller("startActivityAndWait");
2390        WaitResult res = new WaitResult();
2391        int userId = Binder.getOrigCallingUser();
2392        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2393                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2394                res, null, options, userId);
2395        return res;
2396    }
2397
2398    public final int startActivityWithConfig(IApplicationThread caller,
2399            Intent intent, String resolvedType, IBinder resultTo,
2400            String resultWho, int requestCode, int startFlags, Configuration config,
2401            Bundle options) {
2402        enforceNotIsolatedCaller("startActivityWithConfig");
2403        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2404                resultTo, resultWho, requestCode, startFlags,
2405                null, null, null, config, options, Binder.getOrigCallingUser());
2406        return ret;
2407    }
2408
2409    public int startActivityIntentSender(IApplicationThread caller,
2410            IntentSender intent, Intent fillInIntent, String resolvedType,
2411            IBinder resultTo, String resultWho, int requestCode,
2412            int flagsMask, int flagsValues, Bundle options) {
2413        enforceNotIsolatedCaller("startActivityIntentSender");
2414        // Refuse possible leaked file descriptors
2415        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2416            throw new IllegalArgumentException("File descriptors passed in Intent");
2417        }
2418
2419        IIntentSender sender = intent.getTarget();
2420        if (!(sender instanceof PendingIntentRecord)) {
2421            throw new IllegalArgumentException("Bad PendingIntent object");
2422        }
2423
2424        PendingIntentRecord pir = (PendingIntentRecord)sender;
2425
2426        synchronized (this) {
2427            // If this is coming from the currently resumed activity, it is
2428            // effectively saying that app switches are allowed at this point.
2429            if (mMainStack.mResumedActivity != null
2430                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2431                            Binder.getCallingUid()) {
2432                mAppSwitchesAllowedTime = 0;
2433            }
2434        }
2435        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2436                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2437        return ret;
2438    }
2439
2440    public boolean startNextMatchingActivity(IBinder callingActivity,
2441            Intent intent, Bundle options) {
2442        // Refuse possible leaked file descriptors
2443        if (intent != null && intent.hasFileDescriptors() == true) {
2444            throw new IllegalArgumentException("File descriptors passed in Intent");
2445        }
2446
2447        synchronized (this) {
2448            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2449            if (r == null) {
2450                ActivityOptions.abort(options);
2451                return false;
2452            }
2453            if (r.app == null || r.app.thread == null) {
2454                // The caller is not running...  d'oh!
2455                ActivityOptions.abort(options);
2456                return false;
2457            }
2458            intent = new Intent(intent);
2459            // The caller is not allowed to change the data.
2460            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2461            // And we are resetting to find the next component...
2462            intent.setComponent(null);
2463
2464            ActivityInfo aInfo = null;
2465            try {
2466                List<ResolveInfo> resolves =
2467                    AppGlobals.getPackageManager().queryIntentActivities(
2468                            intent, r.resolvedType,
2469                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2470                            UserHandle.getCallingUserId());
2471
2472                // Look for the original activity in the list...
2473                final int N = resolves != null ? resolves.size() : 0;
2474                for (int i=0; i<N; i++) {
2475                    ResolveInfo rInfo = resolves.get(i);
2476                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2477                            && rInfo.activityInfo.name.equals(r.info.name)) {
2478                        // We found the current one...  the next matching is
2479                        // after it.
2480                        i++;
2481                        if (i<N) {
2482                            aInfo = resolves.get(i).activityInfo;
2483                        }
2484                        break;
2485                    }
2486                }
2487            } catch (RemoteException e) {
2488            }
2489
2490            if (aInfo == null) {
2491                // Nobody who is next!
2492                ActivityOptions.abort(options);
2493                return false;
2494            }
2495
2496            intent.setComponent(new ComponentName(
2497                    aInfo.applicationInfo.packageName, aInfo.name));
2498            intent.setFlags(intent.getFlags()&~(
2499                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2500                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2501                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2502                    Intent.FLAG_ACTIVITY_NEW_TASK));
2503
2504            // Okay now we need to start the new activity, replacing the
2505            // currently running activity.  This is a little tricky because
2506            // we want to start the new one as if the current one is finished,
2507            // but not finish the current one first so that there is no flicker.
2508            // And thus...
2509            final boolean wasFinishing = r.finishing;
2510            r.finishing = true;
2511
2512            // Propagate reply information over to the new activity.
2513            final ActivityRecord resultTo = r.resultTo;
2514            final String resultWho = r.resultWho;
2515            final int requestCode = r.requestCode;
2516            r.resultTo = null;
2517            if (resultTo != null) {
2518                resultTo.removeResultsLocked(r, resultWho, requestCode);
2519            }
2520
2521            final long origId = Binder.clearCallingIdentity();
2522            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2523                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2524                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2525                    options, false, null);
2526            Binder.restoreCallingIdentity(origId);
2527
2528            r.finishing = wasFinishing;
2529            if (res != ActivityManager.START_SUCCESS) {
2530                return false;
2531            }
2532            return true;
2533        }
2534    }
2535
2536    public final int startActivityInPackage(int uid,
2537            Intent intent, String resolvedType, IBinder resultTo,
2538            String resultWho, int requestCode, int startFlags, Bundle options) {
2539
2540        // This is so super not safe, that only the system (or okay root)
2541        // can do it.
2542        int userId = Binder.getOrigCallingUser();
2543        final int callingUid = Binder.getCallingUid();
2544        if (callingUid != 0 && callingUid != Process.myUid()) {
2545            throw new SecurityException(
2546                    "startActivityInPackage only available to the system");
2547        }
2548
2549        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2550                resultTo, resultWho, requestCode, startFlags,
2551                null, null, null, null, options, userId);
2552        return ret;
2553    }
2554
2555    public final int startActivities(IApplicationThread caller,
2556            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2557        enforceNotIsolatedCaller("startActivities");
2558        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2559                options, Binder.getOrigCallingUser());
2560        return ret;
2561    }
2562
2563    public final int startActivitiesInPackage(int uid,
2564            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2565            Bundle options) {
2566
2567        // This is so super not safe, that only the system (or okay root)
2568        // can do it.
2569        final int callingUid = Binder.getCallingUid();
2570        if (callingUid != 0 && callingUid != Process.myUid()) {
2571            throw new SecurityException(
2572                    "startActivityInPackage only available to the system");
2573        }
2574        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2575                options, UserHandle.getUserId(uid));
2576        return ret;
2577    }
2578
2579    final void addRecentTaskLocked(TaskRecord task) {
2580        int N = mRecentTasks.size();
2581        // Quick case: check if the top-most recent task is the same.
2582        if (N > 0 && mRecentTasks.get(0) == task) {
2583            return;
2584        }
2585        // Remove any existing entries that are the same kind of task.
2586        for (int i=0; i<N; i++) {
2587            TaskRecord tr = mRecentTasks.get(i);
2588            if (task.userId == tr.userId
2589                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2590                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2591                mRecentTasks.remove(i);
2592                i--;
2593                N--;
2594                if (task.intent == null) {
2595                    // If the new recent task we are adding is not fully
2596                    // specified, then replace it with the existing recent task.
2597                    task = tr;
2598                }
2599            }
2600        }
2601        if (N >= MAX_RECENT_TASKS) {
2602            mRecentTasks.remove(N-1);
2603        }
2604        mRecentTasks.add(0, task);
2605    }
2606
2607    public void setRequestedOrientation(IBinder token,
2608            int requestedOrientation) {
2609        synchronized (this) {
2610            ActivityRecord r = mMainStack.isInStackLocked(token);
2611            if (r == null) {
2612                return;
2613            }
2614            final long origId = Binder.clearCallingIdentity();
2615            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2616            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2617                    mConfiguration,
2618                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2619            if (config != null) {
2620                r.frozenBeforeDestroy = true;
2621                if (!updateConfigurationLocked(config, r, false, false)) {
2622                    mMainStack.resumeTopActivityLocked(null);
2623                }
2624            }
2625            Binder.restoreCallingIdentity(origId);
2626        }
2627    }
2628
2629    public int getRequestedOrientation(IBinder token) {
2630        synchronized (this) {
2631            ActivityRecord r = mMainStack.isInStackLocked(token);
2632            if (r == null) {
2633                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2634            }
2635            return mWindowManager.getAppOrientation(r.appToken);
2636        }
2637    }
2638
2639    /**
2640     * This is the internal entry point for handling Activity.finish().
2641     *
2642     * @param token The Binder token referencing the Activity we want to finish.
2643     * @param resultCode Result code, if any, from this Activity.
2644     * @param resultData Result data (Intent), if any, from this Activity.
2645     *
2646     * @return Returns true if the activity successfully finished, or false if it is still running.
2647     */
2648    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2649        // Refuse possible leaked file descriptors
2650        if (resultData != null && resultData.hasFileDescriptors() == true) {
2651            throw new IllegalArgumentException("File descriptors passed in Intent");
2652        }
2653
2654        synchronized(this) {
2655            if (mController != null) {
2656                // Find the first activity that is not finishing.
2657                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2658                if (next != null) {
2659                    // ask watcher if this is allowed
2660                    boolean resumeOK = true;
2661                    try {
2662                        resumeOK = mController.activityResuming(next.packageName);
2663                    } catch (RemoteException e) {
2664                        mController = null;
2665                    }
2666
2667                    if (!resumeOK) {
2668                        return false;
2669                    }
2670                }
2671            }
2672            final long origId = Binder.clearCallingIdentity();
2673            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2674                    resultData, "app-request");
2675            Binder.restoreCallingIdentity(origId);
2676            return res;
2677        }
2678    }
2679
2680    public final void finishHeavyWeightApp() {
2681        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2682                != PackageManager.PERMISSION_GRANTED) {
2683            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2684                    + Binder.getCallingPid()
2685                    + ", uid=" + Binder.getCallingUid()
2686                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2687            Slog.w(TAG, msg);
2688            throw new SecurityException(msg);
2689        }
2690
2691        synchronized(this) {
2692            if (mHeavyWeightProcess == null) {
2693                return;
2694            }
2695
2696            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2697                    mHeavyWeightProcess.activities);
2698            for (int i=0; i<activities.size(); i++) {
2699                ActivityRecord r = activities.get(i);
2700                if (!r.finishing) {
2701                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2702                    if (index >= 0) {
2703                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2704                                null, "finish-heavy");
2705                    }
2706                }
2707            }
2708
2709            mHeavyWeightProcess = null;
2710            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2711        }
2712    }
2713
2714    public void crashApplication(int uid, int initialPid, String packageName,
2715            String message) {
2716        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2717                != PackageManager.PERMISSION_GRANTED) {
2718            String msg = "Permission Denial: crashApplication() from pid="
2719                    + Binder.getCallingPid()
2720                    + ", uid=" + Binder.getCallingUid()
2721                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2722            Slog.w(TAG, msg);
2723            throw new SecurityException(msg);
2724        }
2725
2726        synchronized(this) {
2727            ProcessRecord proc = null;
2728
2729            // Figure out which process to kill.  We don't trust that initialPid
2730            // still has any relation to current pids, so must scan through the
2731            // list.
2732            synchronized (mPidsSelfLocked) {
2733                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2734                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2735                    if (p.uid != uid) {
2736                        continue;
2737                    }
2738                    if (p.pid == initialPid) {
2739                        proc = p;
2740                        break;
2741                    }
2742                    for (String str : p.pkgList) {
2743                        if (str.equals(packageName)) {
2744                            proc = p;
2745                        }
2746                    }
2747                }
2748            }
2749
2750            if (proc == null) {
2751                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2752                        + " initialPid=" + initialPid
2753                        + " packageName=" + packageName);
2754                return;
2755            }
2756
2757            if (proc.thread != null) {
2758                if (proc.pid == Process.myPid()) {
2759                    Log.w(TAG, "crashApplication: trying to crash self!");
2760                    return;
2761                }
2762                long ident = Binder.clearCallingIdentity();
2763                try {
2764                    proc.thread.scheduleCrash(message);
2765                } catch (RemoteException e) {
2766                }
2767                Binder.restoreCallingIdentity(ident);
2768            }
2769        }
2770    }
2771
2772    public final void finishSubActivity(IBinder token, String resultWho,
2773            int requestCode) {
2774        synchronized(this) {
2775            final long origId = Binder.clearCallingIdentity();
2776            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2777            Binder.restoreCallingIdentity(origId);
2778        }
2779    }
2780
2781    public boolean finishActivityAffinity(IBinder token) {
2782        synchronized(this) {
2783            final long origId = Binder.clearCallingIdentity();
2784            boolean res = mMainStack.finishActivityAffinityLocked(token);
2785            Binder.restoreCallingIdentity(origId);
2786            return res;
2787        }
2788    }
2789
2790    public boolean willActivityBeVisible(IBinder token) {
2791        synchronized(this) {
2792            int i;
2793            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2794                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2795                if (r.appToken == token) {
2796                    return true;
2797                }
2798                if (r.fullscreen && !r.finishing) {
2799                    return false;
2800                }
2801            }
2802            return true;
2803        }
2804    }
2805
2806    public void overridePendingTransition(IBinder token, String packageName,
2807            int enterAnim, int exitAnim) {
2808        synchronized(this) {
2809            ActivityRecord self = mMainStack.isInStackLocked(token);
2810            if (self == null) {
2811                return;
2812            }
2813
2814            final long origId = Binder.clearCallingIdentity();
2815
2816            if (self.state == ActivityState.RESUMED
2817                    || self.state == ActivityState.PAUSING) {
2818                mWindowManager.overridePendingAppTransition(packageName,
2819                        enterAnim, exitAnim, null);
2820            }
2821
2822            Binder.restoreCallingIdentity(origId);
2823        }
2824    }
2825
2826    /**
2827     * Main function for removing an existing process from the activity manager
2828     * as a result of that process going away.  Clears out all connections
2829     * to the process.
2830     */
2831    private final void handleAppDiedLocked(ProcessRecord app,
2832            boolean restarting, boolean allowRestart) {
2833        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2834        if (!restarting) {
2835            mLruProcesses.remove(app);
2836        }
2837
2838        if (mProfileProc == app) {
2839            clearProfilerLocked();
2840        }
2841
2842        // Just in case...
2843        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2844            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2845            mMainStack.mPausingActivity = null;
2846        }
2847        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2848            mMainStack.mLastPausedActivity = null;
2849        }
2850
2851        // Remove this application's activities from active lists.
2852        mMainStack.removeHistoryRecordsForAppLocked(app);
2853
2854        boolean atTop = true;
2855        boolean hasVisibleActivities = false;
2856
2857        // Clean out the history list.
2858        int i = mMainStack.mHistory.size();
2859        if (localLOGV) Slog.v(
2860            TAG, "Removing app " + app + " from history with " + i + " entries");
2861        while (i > 0) {
2862            i--;
2863            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2864            if (localLOGV) Slog.v(
2865                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2866            if (r.app == app) {
2867                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2868                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2869                        RuntimeException here = new RuntimeException("here");
2870                        here.fillInStackTrace();
2871                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2872                                + ": haveState=" + r.haveState
2873                                + " stateNotNeeded=" + r.stateNotNeeded
2874                                + " finishing=" + r.finishing
2875                                + " state=" + r.state, here);
2876                    }
2877                    if (!r.finishing) {
2878                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2879                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2880                                System.identityHashCode(r),
2881                                r.task.taskId, r.shortComponentName,
2882                                "proc died without state saved");
2883                    }
2884                    mMainStack.removeActivityFromHistoryLocked(r);
2885
2886                } else {
2887                    // We have the current state for this activity, so
2888                    // it can be restarted later when needed.
2889                    if (localLOGV) Slog.v(
2890                        TAG, "Keeping entry, setting app to null");
2891                    if (r.visible) {
2892                        hasVisibleActivities = true;
2893                    }
2894                    r.app = null;
2895                    r.nowVisible = false;
2896                    if (!r.haveState) {
2897                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2898                                "App died, clearing saved state of " + r);
2899                        r.icicle = null;
2900                    }
2901                }
2902
2903                r.stack.cleanUpActivityLocked(r, true, true);
2904            }
2905            atTop = false;
2906        }
2907
2908        app.activities.clear();
2909
2910        if (app.instrumentationClass != null) {
2911            Slog.w(TAG, "Crash of app " + app.processName
2912                  + " running instrumentation " + app.instrumentationClass);
2913            Bundle info = new Bundle();
2914            info.putString("shortMsg", "Process crashed.");
2915            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2916        }
2917
2918        if (!restarting) {
2919            if (!mMainStack.resumeTopActivityLocked(null)) {
2920                // If there was nothing to resume, and we are not already
2921                // restarting this process, but there is a visible activity that
2922                // is hosted by the process...  then make sure all visible
2923                // activities are running, taking care of restarting this
2924                // process.
2925                if (hasVisibleActivities) {
2926                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2927                }
2928            }
2929        }
2930    }
2931
2932    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2933        IBinder threadBinder = thread.asBinder();
2934        // Find the application record.
2935        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2936            ProcessRecord rec = mLruProcesses.get(i);
2937            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2938                return i;
2939            }
2940        }
2941        return -1;
2942    }
2943
2944    final ProcessRecord getRecordForAppLocked(
2945            IApplicationThread thread) {
2946        if (thread == null) {
2947            return null;
2948        }
2949
2950        int appIndex = getLRURecordIndexForAppLocked(thread);
2951        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2952    }
2953
2954    final void appDiedLocked(ProcessRecord app, int pid,
2955            IApplicationThread thread) {
2956
2957        mProcDeaths[0]++;
2958
2959        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2960        synchronized (stats) {
2961            stats.noteProcessDiedLocked(app.info.uid, pid);
2962        }
2963
2964        // Clean up already done if the process has been re-started.
2965        if (app.pid == pid && app.thread != null &&
2966                app.thread.asBinder() == thread.asBinder()) {
2967            if (!app.killedBackground) {
2968                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2969                        + ") has died.");
2970            }
2971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2972            if (localLOGV) Slog.v(
2973                TAG, "Dying app: " + app + ", pid: " + pid
2974                + ", thread: " + thread.asBinder());
2975            boolean doLowMem = app.instrumentationClass == null;
2976            handleAppDiedLocked(app, false, true);
2977
2978            if (doLowMem) {
2979                // If there are no longer any background processes running,
2980                // and the app that died was not running instrumentation,
2981                // then tell everyone we are now low on memory.
2982                boolean haveBg = false;
2983                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2984                    ProcessRecord rec = mLruProcesses.get(i);
2985                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2986                        haveBg = true;
2987                        break;
2988                    }
2989                }
2990
2991                if (!haveBg) {
2992                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2993                    long now = SystemClock.uptimeMillis();
2994                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2995                        ProcessRecord rec = mLruProcesses.get(i);
2996                        if (rec != app && rec.thread != null &&
2997                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2998                            // The low memory report is overriding any current
2999                            // state for a GC request.  Make sure to do
3000                            // heavy/important/visible/foreground processes first.
3001                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3002                                rec.lastRequestedGc = 0;
3003                            } else {
3004                                rec.lastRequestedGc = rec.lastLowMemory;
3005                            }
3006                            rec.reportLowMemory = true;
3007                            rec.lastLowMemory = now;
3008                            mProcessesToGc.remove(rec);
3009                            addProcessToGcListLocked(rec);
3010                        }
3011                    }
3012                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3013                    scheduleAppGcsLocked();
3014                }
3015            }
3016        } else if (app.pid != pid) {
3017            // A new process has already been started.
3018            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3019                    + ") has died and restarted (pid " + app.pid + ").");
3020            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3021        } else if (DEBUG_PROCESSES) {
3022            Slog.d(TAG, "Received spurious death notification for thread "
3023                    + thread.asBinder());
3024        }
3025    }
3026
3027    /**
3028     * If a stack trace dump file is configured, dump process stack traces.
3029     * @param clearTraces causes the dump file to be erased prior to the new
3030     *    traces being written, if true; when false, the new traces will be
3031     *    appended to any existing file content.
3032     * @param firstPids of dalvik VM processes to dump stack traces for first
3033     * @param lastPids of dalvik VM processes to dump stack traces for last
3034     * @param nativeProcs optional list of native process names to dump stack crawls
3035     * @return file containing stack traces, or null if no dump file is configured
3036     */
3037    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3038            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3039        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3040        if (tracesPath == null || tracesPath.length() == 0) {
3041            return null;
3042        }
3043
3044        File tracesFile = new File(tracesPath);
3045        try {
3046            File tracesDir = tracesFile.getParentFile();
3047            if (!tracesDir.exists()) tracesFile.mkdirs();
3048            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3049
3050            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3051            tracesFile.createNewFile();
3052            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3053        } catch (IOException e) {
3054            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3055            return null;
3056        }
3057
3058        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3059        return tracesFile;
3060    }
3061
3062    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3063            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3064        // Use a FileObserver to detect when traces finish writing.
3065        // The order of traces is considered important to maintain for legibility.
3066        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3067            public synchronized void onEvent(int event, String path) { notify(); }
3068        };
3069
3070        try {
3071            observer.startWatching();
3072
3073            // First collect all of the stacks of the most important pids.
3074            if (firstPids != null) {
3075                try {
3076                    int num = firstPids.size();
3077                    for (int i = 0; i < num; i++) {
3078                        synchronized (observer) {
3079                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3080                            observer.wait(200);  // Wait for write-close, give up after 200msec
3081                        }
3082                    }
3083                } catch (InterruptedException e) {
3084                    Log.wtf(TAG, e);
3085                }
3086            }
3087
3088            // Next measure CPU usage.
3089            if (processStats != null) {
3090                processStats.init();
3091                System.gc();
3092                processStats.update();
3093                try {
3094                    synchronized (processStats) {
3095                        processStats.wait(500); // measure over 1/2 second.
3096                    }
3097                } catch (InterruptedException e) {
3098                }
3099                processStats.update();
3100
3101                // We'll take the stack crawls of just the top apps using CPU.
3102                final int N = processStats.countWorkingStats();
3103                int numProcs = 0;
3104                for (int i=0; i<N && numProcs<5; i++) {
3105                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3106                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3107                        numProcs++;
3108                        try {
3109                            synchronized (observer) {
3110                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3111                                observer.wait(200);  // Wait for write-close, give up after 200msec
3112                            }
3113                        } catch (InterruptedException e) {
3114                            Log.wtf(TAG, e);
3115                        }
3116
3117                    }
3118                }
3119            }
3120
3121        } finally {
3122            observer.stopWatching();
3123        }
3124
3125        if (nativeProcs != null) {
3126            int[] pids = Process.getPidsForCommands(nativeProcs);
3127            if (pids != null) {
3128                for (int pid : pids) {
3129                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3130                }
3131            }
3132        }
3133    }
3134
3135    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3136        if (true || IS_USER_BUILD) {
3137            return;
3138        }
3139        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3140        if (tracesPath == null || tracesPath.length() == 0) {
3141            return;
3142        }
3143
3144        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3145        StrictMode.allowThreadDiskWrites();
3146        try {
3147            final File tracesFile = new File(tracesPath);
3148            final File tracesDir = tracesFile.getParentFile();
3149            final File tracesTmp = new File(tracesDir, "__tmp__");
3150            try {
3151                if (!tracesDir.exists()) tracesFile.mkdirs();
3152                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3153
3154                if (tracesFile.exists()) {
3155                    tracesTmp.delete();
3156                    tracesFile.renameTo(tracesTmp);
3157                }
3158                StringBuilder sb = new StringBuilder();
3159                Time tobj = new Time();
3160                tobj.set(System.currentTimeMillis());
3161                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3162                sb.append(": ");
3163                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3164                sb.append(" since ");
3165                sb.append(msg);
3166                FileOutputStream fos = new FileOutputStream(tracesFile);
3167                fos.write(sb.toString().getBytes());
3168                if (app == null) {
3169                    fos.write("\n*** No application process!".getBytes());
3170                }
3171                fos.close();
3172                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3173            } catch (IOException e) {
3174                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3175                return;
3176            }
3177
3178            if (app != null) {
3179                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3180                firstPids.add(app.pid);
3181                dumpStackTraces(tracesPath, firstPids, null, null, null);
3182            }
3183
3184            File lastTracesFile = null;
3185            File curTracesFile = null;
3186            for (int i=9; i>=0; i--) {
3187                String name = String.format("slow%02d.txt", i);
3188                curTracesFile = new File(tracesDir, name);
3189                if (curTracesFile.exists()) {
3190                    if (lastTracesFile != null) {
3191                        curTracesFile.renameTo(lastTracesFile);
3192                    } else {
3193                        curTracesFile.delete();
3194                    }
3195                }
3196                lastTracesFile = curTracesFile;
3197            }
3198            tracesFile.renameTo(curTracesFile);
3199            if (tracesTmp.exists()) {
3200                tracesTmp.renameTo(tracesFile);
3201            }
3202        } finally {
3203            StrictMode.setThreadPolicy(oldPolicy);
3204        }
3205    }
3206
3207    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3208            ActivityRecord parent, final String annotation) {
3209        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3210        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3211
3212        if (mController != null) {
3213            try {
3214                // 0 == continue, -1 = kill process immediately
3215                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3216                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3217            } catch (RemoteException e) {
3218                mController = null;
3219            }
3220        }
3221
3222        long anrTime = SystemClock.uptimeMillis();
3223        if (MONITOR_CPU_USAGE) {
3224            updateCpuStatsNow();
3225        }
3226
3227        synchronized (this) {
3228            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3229            if (mShuttingDown) {
3230                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3231                return;
3232            } else if (app.notResponding) {
3233                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3234                return;
3235            } else if (app.crashing) {
3236                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3237                return;
3238            }
3239
3240            // In case we come through here for the same app before completing
3241            // this one, mark as anring now so we will bail out.
3242            app.notResponding = true;
3243
3244            // Log the ANR to the event log.
3245            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3246                    annotation);
3247
3248            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3249            firstPids.add(app.pid);
3250
3251            int parentPid = app.pid;
3252            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3253            if (parentPid != app.pid) firstPids.add(parentPid);
3254
3255            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3256
3257            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3258                ProcessRecord r = mLruProcesses.get(i);
3259                if (r != null && r.thread != null) {
3260                    int pid = r.pid;
3261                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3262                        if (r.persistent) {
3263                            firstPids.add(pid);
3264                        } else {
3265                            lastPids.put(pid, Boolean.TRUE);
3266                        }
3267                    }
3268                }
3269            }
3270        }
3271
3272        // Log the ANR to the main log.
3273        StringBuilder info = new StringBuilder();
3274        info.setLength(0);
3275        info.append("ANR in ").append(app.processName);
3276        if (activity != null && activity.shortComponentName != null) {
3277            info.append(" (").append(activity.shortComponentName).append(")");
3278        }
3279        info.append("\n");
3280        if (annotation != null) {
3281            info.append("Reason: ").append(annotation).append("\n");
3282        }
3283        if (parent != null && parent != activity) {
3284            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3285        }
3286
3287        final ProcessStats processStats = new ProcessStats(true);
3288
3289        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3290
3291        String cpuInfo = null;
3292        if (MONITOR_CPU_USAGE) {
3293            updateCpuStatsNow();
3294            synchronized (mProcessStatsThread) {
3295                cpuInfo = mProcessStats.printCurrentState(anrTime);
3296            }
3297            info.append(processStats.printCurrentLoad());
3298            info.append(cpuInfo);
3299        }
3300
3301        info.append(processStats.printCurrentState(anrTime));
3302
3303        Slog.e(TAG, info.toString());
3304        if (tracesFile == null) {
3305            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3306            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3307        }
3308
3309        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3310                cpuInfo, tracesFile, null);
3311
3312        if (mController != null) {
3313            try {
3314                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3315                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3316                if (res != 0) {
3317                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3318                    return;
3319                }
3320            } catch (RemoteException e) {
3321                mController = null;
3322            }
3323        }
3324
3325        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3326        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3327                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3328
3329        synchronized (this) {
3330            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3331                Slog.w(TAG, "Killing " + app + ": background ANR");
3332                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3333                        app.processName, app.setAdj, "background ANR");
3334                Process.killProcessQuiet(app.pid);
3335                return;
3336            }
3337
3338            // Set the app's notResponding state, and look up the errorReportReceiver
3339            makeAppNotRespondingLocked(app,
3340                    activity != null ? activity.shortComponentName : null,
3341                    annotation != null ? "ANR " + annotation : "ANR",
3342                    info.toString());
3343
3344            // Bring up the infamous App Not Responding dialog
3345            Message msg = Message.obtain();
3346            HashMap map = new HashMap();
3347            msg.what = SHOW_NOT_RESPONDING_MSG;
3348            msg.obj = map;
3349            map.put("app", app);
3350            if (activity != null) {
3351                map.put("activity", activity);
3352            }
3353
3354            mHandler.sendMessage(msg);
3355        }
3356    }
3357
3358    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3359        if (!mLaunchWarningShown) {
3360            mLaunchWarningShown = true;
3361            mHandler.post(new Runnable() {
3362                @Override
3363                public void run() {
3364                    synchronized (ActivityManagerService.this) {
3365                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3366                        d.show();
3367                        mHandler.postDelayed(new Runnable() {
3368                            @Override
3369                            public void run() {
3370                                synchronized (ActivityManagerService.this) {
3371                                    d.dismiss();
3372                                    mLaunchWarningShown = false;
3373                                }
3374                            }
3375                        }, 4000);
3376                    }
3377                }
3378            });
3379        }
3380    }
3381
3382    public boolean clearApplicationUserData(final String packageName,
3383            final IPackageDataObserver observer, final int userId) {
3384        enforceNotIsolatedCaller("clearApplicationUserData");
3385        int uid = Binder.getCallingUid();
3386        int pid = Binder.getCallingPid();
3387        long callingId = Binder.clearCallingIdentity();
3388        try {
3389            IPackageManager pm = AppGlobals.getPackageManager();
3390            int pkgUid = -1;
3391            synchronized(this) {
3392                try {
3393                    pkgUid = pm.getPackageUid(packageName, userId);
3394                } catch (RemoteException e) {
3395                }
3396                if (pkgUid == -1) {
3397                    Slog.w(TAG, "Invalid packageName:" + packageName);
3398                    return false;
3399                }
3400                if (uid == pkgUid || checkComponentPermission(
3401                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3402                        pid, uid, -1, true)
3403                        == PackageManager.PERMISSION_GRANTED) {
3404                    forceStopPackageLocked(packageName, pkgUid);
3405                } else {
3406                    throw new SecurityException(pid+" does not have permission:"+
3407                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3408                                    "for process:"+packageName);
3409                }
3410            }
3411
3412            try {
3413                //clear application user data
3414                pm.clearApplicationUserData(packageName, observer, userId);
3415                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3416                        Uri.fromParts("package", packageName, null));
3417                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3418                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3419                        null, null, 0, null, null, null, false, false, userId);
3420            } catch (RemoteException e) {
3421            }
3422        } finally {
3423            Binder.restoreCallingIdentity(callingId);
3424        }
3425        return true;
3426    }
3427
3428    public void killBackgroundProcesses(final String packageName) {
3429        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3430                != PackageManager.PERMISSION_GRANTED &&
3431                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3432                        != PackageManager.PERMISSION_GRANTED) {
3433            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3434                    + Binder.getCallingPid()
3435                    + ", uid=" + Binder.getCallingUid()
3436                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3437            Slog.w(TAG, msg);
3438            throw new SecurityException(msg);
3439        }
3440
3441        int userId = UserHandle.getCallingUserId();
3442        long callingId = Binder.clearCallingIdentity();
3443        try {
3444            IPackageManager pm = AppGlobals.getPackageManager();
3445            int pkgUid = -1;
3446            synchronized(this) {
3447                try {
3448                    pkgUid = pm.getPackageUid(packageName, userId);
3449                } catch (RemoteException e) {
3450                }
3451                if (pkgUid == -1) {
3452                    Slog.w(TAG, "Invalid packageName: " + packageName);
3453                    return;
3454                }
3455                killPackageProcessesLocked(packageName, pkgUid,
3456                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3457            }
3458        } finally {
3459            Binder.restoreCallingIdentity(callingId);
3460        }
3461    }
3462
3463    public void killAllBackgroundProcesses() {
3464        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3465                != PackageManager.PERMISSION_GRANTED) {
3466            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3467                    + Binder.getCallingPid()
3468                    + ", uid=" + Binder.getCallingUid()
3469                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3470            Slog.w(TAG, msg);
3471            throw new SecurityException(msg);
3472        }
3473
3474        long callingId = Binder.clearCallingIdentity();
3475        try {
3476            synchronized(this) {
3477                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3478                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3479                    final int NA = apps.size();
3480                    for (int ia=0; ia<NA; ia++) {
3481                        ProcessRecord app = apps.valueAt(ia);
3482                        if (app.persistent) {
3483                            // we don't kill persistent processes
3484                            continue;
3485                        }
3486                        if (app.removed) {
3487                            procs.add(app);
3488                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3489                            app.removed = true;
3490                            procs.add(app);
3491                        }
3492                    }
3493                }
3494
3495                int N = procs.size();
3496                for (int i=0; i<N; i++) {
3497                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3498                }
3499            }
3500        } finally {
3501            Binder.restoreCallingIdentity(callingId);
3502        }
3503    }
3504
3505    public void forceStopPackage(final String packageName) {
3506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3507                != PackageManager.PERMISSION_GRANTED) {
3508            String msg = "Permission Denial: forceStopPackage() from pid="
3509                    + Binder.getCallingPid()
3510                    + ", uid=" + Binder.getCallingUid()
3511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3512            Slog.w(TAG, msg);
3513            throw new SecurityException(msg);
3514        }
3515        final int userId = UserHandle.getCallingUserId();
3516        long callingId = Binder.clearCallingIdentity();
3517        try {
3518            IPackageManager pm = AppGlobals.getPackageManager();
3519            int pkgUid = -1;
3520            synchronized(this) {
3521                try {
3522                    pkgUid = pm.getPackageUid(packageName, userId);
3523                } catch (RemoteException e) {
3524                }
3525                if (pkgUid == -1) {
3526                    Slog.w(TAG, "Invalid packageName: " + packageName);
3527                    return;
3528                }
3529                forceStopPackageLocked(packageName, pkgUid);
3530                try {
3531                    pm.setPackageStoppedState(packageName, true, userId);
3532                } catch (RemoteException e) {
3533                } catch (IllegalArgumentException e) {
3534                    Slog.w(TAG, "Failed trying to unstop package "
3535                            + packageName + ": " + e);
3536                }
3537            }
3538        } finally {
3539            Binder.restoreCallingIdentity(callingId);
3540        }
3541    }
3542
3543    /*
3544     * The pkg name and uid have to be specified.
3545     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3546     */
3547    public void killApplicationWithUid(String pkg, int uid) {
3548        if (pkg == null) {
3549            return;
3550        }
3551        // Make sure the uid is valid.
3552        if (uid < 0) {
3553            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3554            return;
3555        }
3556        int callerUid = Binder.getCallingUid();
3557        // Only the system server can kill an application
3558        if (callerUid == Process.SYSTEM_UID) {
3559            // Post an aysnc message to kill the application
3560            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3561            msg.arg1 = uid;
3562            msg.arg2 = 0;
3563            msg.obj = pkg;
3564            mHandler.sendMessage(msg);
3565        } else {
3566            throw new SecurityException(callerUid + " cannot kill pkg: " +
3567                    pkg);
3568        }
3569    }
3570
3571    public void closeSystemDialogs(String reason) {
3572        enforceNotIsolatedCaller("closeSystemDialogs");
3573
3574        final int uid = Binder.getCallingUid();
3575        final long origId = Binder.clearCallingIdentity();
3576        synchronized (this) {
3577            closeSystemDialogsLocked(uid, reason);
3578        }
3579        Binder.restoreCallingIdentity(origId);
3580    }
3581
3582    void closeSystemDialogsLocked(int callingUid, String reason) {
3583        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3584        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3585        if (reason != null) {
3586            intent.putExtra("reason", reason);
3587        }
3588        mWindowManager.closeSystemDialogs(reason);
3589
3590        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3591            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3592            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3593                r.stack.finishActivityLocked(r, i,
3594                        Activity.RESULT_CANCELED, null, "close-sys");
3595            }
3596        }
3597
3598        broadcastIntentLocked(null, null, intent, null,
3599                null, 0, null, null, null, false, false, -1,
3600                callingUid, 0 /* TODO: Verify */);
3601    }
3602
3603    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3604            throws RemoteException {
3605        enforceNotIsolatedCaller("getProcessMemoryInfo");
3606        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3607        for (int i=pids.length-1; i>=0; i--) {
3608            infos[i] = new Debug.MemoryInfo();
3609            Debug.getMemoryInfo(pids[i], infos[i]);
3610        }
3611        return infos;
3612    }
3613
3614    public long[] getProcessPss(int[] pids) throws RemoteException {
3615        enforceNotIsolatedCaller("getProcessPss");
3616        long[] pss = new long[pids.length];
3617        for (int i=pids.length-1; i>=0; i--) {
3618            pss[i] = Debug.getPss(pids[i]);
3619        }
3620        return pss;
3621    }
3622
3623    public void killApplicationProcess(String processName, int uid) {
3624        if (processName == null) {
3625            return;
3626        }
3627
3628        int callerUid = Binder.getCallingUid();
3629        // Only the system server can kill an application
3630        if (callerUid == Process.SYSTEM_UID) {
3631            synchronized (this) {
3632                ProcessRecord app = getProcessRecordLocked(processName, uid);
3633                if (app != null && app.thread != null) {
3634                    try {
3635                        app.thread.scheduleSuicide();
3636                    } catch (RemoteException e) {
3637                        // If the other end already died, then our work here is done.
3638                    }
3639                } else {
3640                    Slog.w(TAG, "Process/uid not found attempting kill of "
3641                            + processName + " / " + uid);
3642                }
3643            }
3644        } else {
3645            throw new SecurityException(callerUid + " cannot kill app process: " +
3646                    processName);
3647        }
3648    }
3649
3650    private void forceStopPackageLocked(final String packageName, int uid) {
3651        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3652        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3653                Uri.fromParts("package", packageName, null));
3654        if (!mProcessesReady) {
3655            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3656        }
3657        intent.putExtra(Intent.EXTRA_UID, uid);
3658        broadcastIntentLocked(null, null, intent,
3659                null, null, 0, null, null, null,
3660                false, false,
3661                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3662    }
3663
3664    private final boolean killPackageProcessesLocked(String packageName, int uid,
3665            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3666            boolean evenPersistent, String reason) {
3667        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3668
3669        // Remove all processes this package may have touched: all with the
3670        // same UID (except for the system or root user), and all whose name
3671        // matches the package name.
3672        final String procNamePrefix = packageName + ":";
3673        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3674            final int NA = apps.size();
3675            for (int ia=0; ia<NA; ia++) {
3676                ProcessRecord app = apps.valueAt(ia);
3677                if (app.persistent && !evenPersistent) {
3678                    // we don't kill persistent processes
3679                    continue;
3680                }
3681                if (app.removed) {
3682                    if (doit) {
3683                        procs.add(app);
3684                    }
3685                // If uid is specified and the uid and process name match
3686                // Or, the uid is not specified and the process name matches
3687                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3688                            || ((app.processName.equals(packageName)
3689                                 || app.processName.startsWith(procNamePrefix))
3690                                && uid < 0))) {
3691                    if (app.setAdj >= minOomAdj) {
3692                        if (!doit) {
3693                            return true;
3694                        }
3695                        app.removed = true;
3696                        procs.add(app);
3697                    }
3698                }
3699            }
3700        }
3701
3702        int N = procs.size();
3703        for (int i=0; i<N; i++) {
3704            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3705        }
3706        return N > 0;
3707    }
3708
3709    private final boolean forceStopPackageLocked(String name, int uid,
3710            boolean callerWillRestart, boolean purgeCache, boolean doit,
3711            boolean evenPersistent, int userId) {
3712        int i;
3713        int N;
3714
3715        if (uid < 0) {
3716            try {
3717                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3718            } catch (RemoteException e) {
3719            }
3720        }
3721
3722        if (doit) {
3723            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3724
3725            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3726            while (badApps.hasNext()) {
3727                SparseArray<Long> ba = badApps.next();
3728                if (ba.get(uid) != null) {
3729                    badApps.remove();
3730                }
3731            }
3732        }
3733
3734        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3735                callerWillRestart, false, doit, evenPersistent, "force stop");
3736
3737        TaskRecord lastTask = null;
3738        for (i=0; i<mMainStack.mHistory.size(); i++) {
3739            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3740            final boolean samePackage = r.packageName.equals(name);
3741            if (r.userId == userId
3742                    && (samePackage || r.task == lastTask)
3743                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3744                if (!doit) {
3745                    if (r.finishing) {
3746                        // If this activity is just finishing, then it is not
3747                        // interesting as far as something to stop.
3748                        continue;
3749                    }
3750                    return true;
3751                }
3752                didSomething = true;
3753                Slog.i(TAG, "  Force finishing activity " + r);
3754                if (samePackage) {
3755                    if (r.app != null) {
3756                        r.app.removed = true;
3757                    }
3758                    r.app = null;
3759                }
3760                lastTask = r.task;
3761                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3762                        null, "force-stop", true)) {
3763                    i--;
3764                }
3765            }
3766        }
3767
3768        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3769            if (!doit) {
3770                return true;
3771            }
3772            didSomething = true;
3773        }
3774
3775        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3776        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3777            if (provider.info.packageName.equals(name)
3778                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3779                if (!doit) {
3780                    return true;
3781                }
3782                didSomething = true;
3783                providers.add(provider);
3784            }
3785        }
3786
3787        N = providers.size();
3788        for (i=0; i<N; i++) {
3789            removeDyingProviderLocked(null, providers.get(i), true);
3790        }
3791
3792        if (doit) {
3793            if (purgeCache) {
3794                AttributeCache ac = AttributeCache.instance();
3795                if (ac != null) {
3796                    ac.removePackage(name);
3797                }
3798            }
3799            if (mBooted) {
3800                mMainStack.resumeTopActivityLocked(null);
3801                mMainStack.scheduleIdleLocked();
3802            }
3803        }
3804
3805        return didSomething;
3806    }
3807
3808    private final boolean removeProcessLocked(ProcessRecord app,
3809            boolean callerWillRestart, boolean allowRestart, String reason) {
3810        final String name = app.processName;
3811        final int uid = app.uid;
3812        if (DEBUG_PROCESSES) Slog.d(
3813            TAG, "Force removing proc " + app.toShortString() + " (" + name
3814            + "/" + uid + ")");
3815
3816        mProcessNames.remove(name, uid);
3817        mIsolatedProcesses.remove(app.uid);
3818        if (mHeavyWeightProcess == app) {
3819            mHeavyWeightProcess = null;
3820            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3821        }
3822        boolean needRestart = false;
3823        if (app.pid > 0 && app.pid != MY_PID) {
3824            int pid = app.pid;
3825            synchronized (mPidsSelfLocked) {
3826                mPidsSelfLocked.remove(pid);
3827                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3828            }
3829            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3830            handleAppDiedLocked(app, true, allowRestart);
3831            mLruProcesses.remove(app);
3832            Process.killProcessQuiet(pid);
3833
3834            if (app.persistent && !app.isolated) {
3835                if (!callerWillRestart) {
3836                    addAppLocked(app.info, false);
3837                } else {
3838                    needRestart = true;
3839                }
3840            }
3841        } else {
3842            mRemovedProcesses.add(app);
3843        }
3844
3845        return needRestart;
3846    }
3847
3848    private final void processStartTimedOutLocked(ProcessRecord app) {
3849        final int pid = app.pid;
3850        boolean gone = false;
3851        synchronized (mPidsSelfLocked) {
3852            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3853            if (knownApp != null && knownApp.thread == null) {
3854                mPidsSelfLocked.remove(pid);
3855                gone = true;
3856            }
3857        }
3858
3859        if (gone) {
3860            Slog.w(TAG, "Process " + app + " failed to attach");
3861            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3862                    app.processName);
3863            mProcessNames.remove(app.processName, app.uid);
3864            mIsolatedProcesses.remove(app.uid);
3865            if (mHeavyWeightProcess == app) {
3866                mHeavyWeightProcess = null;
3867                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3868            }
3869            // Take care of any launching providers waiting for this process.
3870            checkAppInLaunchingProvidersLocked(app, true);
3871            // Take care of any services that are waiting for the process.
3872            mServices.processStartTimedOutLocked(app);
3873            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3874                    app.processName, app.setAdj, "start timeout");
3875            Process.killProcessQuiet(pid);
3876            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3877                Slog.w(TAG, "Unattached app died before backup, skipping");
3878                try {
3879                    IBackupManager bm = IBackupManager.Stub.asInterface(
3880                            ServiceManager.getService(Context.BACKUP_SERVICE));
3881                    bm.agentDisconnected(app.info.packageName);
3882                } catch (RemoteException e) {
3883                    // Can't happen; the backup manager is local
3884                }
3885            }
3886            if (isPendingBroadcastProcessLocked(pid)) {
3887                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3888                skipPendingBroadcastLocked(pid);
3889            }
3890        } else {
3891            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3892        }
3893    }
3894
3895    private final boolean attachApplicationLocked(IApplicationThread thread,
3896            int pid) {
3897
3898        // Find the application record that is being attached...  either via
3899        // the pid if we are running in multiple processes, or just pull the
3900        // next app record if we are emulating process with anonymous threads.
3901        ProcessRecord app;
3902        if (pid != MY_PID && pid >= 0) {
3903            synchronized (mPidsSelfLocked) {
3904                app = mPidsSelfLocked.get(pid);
3905            }
3906        } else {
3907            app = null;
3908        }
3909
3910        if (app == null) {
3911            Slog.w(TAG, "No pending application record for pid " + pid
3912                    + " (IApplicationThread " + thread + "); dropping process");
3913            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3914            if (pid > 0 && pid != MY_PID) {
3915                Process.killProcessQuiet(pid);
3916            } else {
3917                try {
3918                    thread.scheduleExit();
3919                } catch (Exception e) {
3920                    // Ignore exceptions.
3921                }
3922            }
3923            return false;
3924        }
3925
3926        // If this application record is still attached to a previous
3927        // process, clean it up now.
3928        if (app.thread != null) {
3929            handleAppDiedLocked(app, true, true);
3930        }
3931
3932        // Tell the process all about itself.
3933
3934        if (localLOGV) Slog.v(
3935                TAG, "Binding process pid " + pid + " to record " + app);
3936
3937        String processName = app.processName;
3938        try {
3939            AppDeathRecipient adr = new AppDeathRecipient(
3940                    app, pid, thread);
3941            thread.asBinder().linkToDeath(adr, 0);
3942            app.deathRecipient = adr;
3943        } catch (RemoteException e) {
3944            app.resetPackageList();
3945            startProcessLocked(app, "link fail", processName);
3946            return false;
3947        }
3948
3949        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3950
3951        app.thread = thread;
3952        app.curAdj = app.setAdj = -100;
3953        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3954        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3955        app.forcingToForeground = null;
3956        app.foregroundServices = false;
3957        app.hasShownUi = false;
3958        app.debugging = false;
3959
3960        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3961
3962        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3963        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3964
3965        if (!normalMode) {
3966            Slog.i(TAG, "Launching preboot mode app: " + app);
3967        }
3968
3969        if (localLOGV) Slog.v(
3970            TAG, "New app record " + app
3971            + " thread=" + thread.asBinder() + " pid=" + pid);
3972        try {
3973            int testMode = IApplicationThread.DEBUG_OFF;
3974            if (mDebugApp != null && mDebugApp.equals(processName)) {
3975                testMode = mWaitForDebugger
3976                    ? IApplicationThread.DEBUG_WAIT
3977                    : IApplicationThread.DEBUG_ON;
3978                app.debugging = true;
3979                if (mDebugTransient) {
3980                    mDebugApp = mOrigDebugApp;
3981                    mWaitForDebugger = mOrigWaitForDebugger;
3982                }
3983            }
3984            String profileFile = app.instrumentationProfileFile;
3985            ParcelFileDescriptor profileFd = null;
3986            boolean profileAutoStop = false;
3987            if (mProfileApp != null && mProfileApp.equals(processName)) {
3988                mProfileProc = app;
3989                profileFile = mProfileFile;
3990                profileFd = mProfileFd;
3991                profileAutoStop = mAutoStopProfiler;
3992            }
3993            boolean enableOpenGlTrace = false;
3994            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3995                enableOpenGlTrace = true;
3996                mOpenGlTraceApp = null;
3997            }
3998
3999            // If the app is being launched for restore or full backup, set it up specially
4000            boolean isRestrictedBackupMode = false;
4001            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4002                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4003                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4004                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4005            }
4006
4007            ensurePackageDexOpt(app.instrumentationInfo != null
4008                    ? app.instrumentationInfo.packageName
4009                    : app.info.packageName);
4010            if (app.instrumentationClass != null) {
4011                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4012            }
4013            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4014                    + processName + " with config " + mConfiguration);
4015            ApplicationInfo appInfo = app.instrumentationInfo != null
4016                    ? app.instrumentationInfo : app.info;
4017            app.compat = compatibilityInfoForPackageLocked(appInfo);
4018            if (profileFd != null) {
4019                profileFd = profileFd.dup();
4020            }
4021            thread.bindApplication(processName, appInfo, providers,
4022                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4023                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4024                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4025                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4026                    mCoreSettingsObserver.getCoreSettingsLocked());
4027            updateLruProcessLocked(app, false, true);
4028            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4029        } catch (Exception e) {
4030            // todo: Yikes!  What should we do?  For now we will try to
4031            // start another process, but that could easily get us in
4032            // an infinite loop of restarting processes...
4033            Slog.w(TAG, "Exception thrown during bind!", e);
4034
4035            app.resetPackageList();
4036            app.unlinkDeathRecipient();
4037            startProcessLocked(app, "bind fail", processName);
4038            return false;
4039        }
4040
4041        // Remove this record from the list of starting applications.
4042        mPersistentStartingProcesses.remove(app);
4043        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4044                "Attach application locked removing on hold: " + app);
4045        mProcessesOnHold.remove(app);
4046
4047        boolean badApp = false;
4048        boolean didSomething = false;
4049
4050        // See if the top visible activity is waiting to run in this process...
4051        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4052        if (hr != null && normalMode) {
4053            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4054                    && processName.equals(hr.processName)) {
4055                try {
4056                    if (mHeadless) {
4057                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4058                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4059                        didSomething = true;
4060                    }
4061                } catch (Exception e) {
4062                    Slog.w(TAG, "Exception in new application when starting activity "
4063                          + hr.intent.getComponent().flattenToShortString(), e);
4064                    badApp = true;
4065                }
4066            } else {
4067                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4068            }
4069        }
4070
4071        // Find any services that should be running in this process...
4072        if (!badApp) {
4073            try {
4074                didSomething |= mServices.attachApplicationLocked(app, processName);
4075            } catch (Exception e) {
4076                badApp = true;
4077            }
4078        }
4079
4080        // Check if a next-broadcast receiver is in this process...
4081        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4082            try {
4083                didSomething = sendPendingBroadcastsLocked(app);
4084            } catch (Exception e) {
4085                // If the app died trying to launch the receiver we declare it 'bad'
4086                badApp = true;
4087            }
4088        }
4089
4090        // Check whether the next backup agent is in this process...
4091        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4092            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4093            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4094            try {
4095                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4096                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4097                        mBackupTarget.backupMode);
4098            } catch (Exception e) {
4099                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4100                e.printStackTrace();
4101            }
4102        }
4103
4104        if (badApp) {
4105            // todo: Also need to kill application to deal with all
4106            // kinds of exceptions.
4107            handleAppDiedLocked(app, false, true);
4108            return false;
4109        }
4110
4111        if (!didSomething) {
4112            updateOomAdjLocked();
4113        }
4114
4115        return true;
4116    }
4117
4118    public final void attachApplication(IApplicationThread thread) {
4119        synchronized (this) {
4120            int callingPid = Binder.getCallingPid();
4121            final long origId = Binder.clearCallingIdentity();
4122            attachApplicationLocked(thread, callingPid);
4123            Binder.restoreCallingIdentity(origId);
4124        }
4125    }
4126
4127    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4128        final long origId = Binder.clearCallingIdentity();
4129        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4130        if (stopProfiling) {
4131            synchronized (this) {
4132                if (mProfileProc == r.app) {
4133                    if (mProfileFd != null) {
4134                        try {
4135                            mProfileFd.close();
4136                        } catch (IOException e) {
4137                        }
4138                        clearProfilerLocked();
4139                    }
4140                }
4141            }
4142        }
4143        Binder.restoreCallingIdentity(origId);
4144    }
4145
4146    void enableScreenAfterBoot() {
4147        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4148                SystemClock.uptimeMillis());
4149        mWindowManager.enableScreenAfterBoot();
4150
4151        synchronized (this) {
4152            updateEventDispatchingLocked();
4153        }
4154    }
4155
4156    public void showBootMessage(final CharSequence msg, final boolean always) {
4157        enforceNotIsolatedCaller("showBootMessage");
4158        mWindowManager.showBootMessage(msg, always);
4159    }
4160
4161    public void dismissKeyguardOnNextActivity() {
4162        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4163        final long token = Binder.clearCallingIdentity();
4164        try {
4165            synchronized (this) {
4166                if (mLockScreenShown) {
4167                    mLockScreenShown = false;
4168                    comeOutOfSleepIfNeededLocked();
4169                }
4170                mMainStack.dismissKeyguardOnNextActivityLocked();
4171            }
4172        } finally {
4173            Binder.restoreCallingIdentity(token);
4174        }
4175    }
4176
4177    final void finishBooting() {
4178        IntentFilter pkgFilter = new IntentFilter();
4179        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4180        pkgFilter.addDataScheme("package");
4181        mContext.registerReceiver(new BroadcastReceiver() {
4182            @Override
4183            public void onReceive(Context context, Intent intent) {
4184                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4185                if (pkgs != null) {
4186                    for (String pkg : pkgs) {
4187                        synchronized (ActivityManagerService.this) {
4188                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4189                                setResultCode(Activity.RESULT_OK);
4190                                return;
4191                            }
4192                        }
4193                    }
4194                }
4195            }
4196        }, pkgFilter);
4197
4198        IntentFilter userFilter = new IntentFilter();
4199        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4200        mContext.registerReceiver(new BroadcastReceiver() {
4201            @Override
4202            public void onReceive(Context context, Intent intent) {
4203                onUserRemoved(intent);
4204            }
4205        }, userFilter);
4206
4207        synchronized (this) {
4208            // Ensure that any processes we had put on hold are now started
4209            // up.
4210            final int NP = mProcessesOnHold.size();
4211            if (NP > 0) {
4212                ArrayList<ProcessRecord> procs =
4213                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4214                for (int ip=0; ip<NP; ip++) {
4215                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4216                            + procs.get(ip));
4217                    startProcessLocked(procs.get(ip), "on-hold", null);
4218                }
4219            }
4220
4221            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4222                // Start looking for apps that are abusing wake locks.
4223                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4224                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4225                // Tell anyone interested that we are done booting!
4226                SystemProperties.set("sys.boot_completed", "1");
4227                SystemProperties.set("dev.bootcomplete", "1");
4228                List<UserInfo> users = getUserManager().getUsers();
4229                for (UserInfo user : users) {
4230                    broadcastIntentLocked(null, null,
4231                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4232                            null, null, 0, null, null,
4233                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4234                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4235                }
4236            }
4237        }
4238    }
4239
4240    final void ensureBootCompleted() {
4241        boolean booting;
4242        boolean enableScreen;
4243        synchronized (this) {
4244            booting = mBooting;
4245            mBooting = false;
4246            enableScreen = !mBooted;
4247            mBooted = true;
4248        }
4249
4250        if (booting) {
4251            finishBooting();
4252        }
4253
4254        if (enableScreen) {
4255            enableScreenAfterBoot();
4256        }
4257    }
4258
4259    public final void activityPaused(IBinder token) {
4260        final long origId = Binder.clearCallingIdentity();
4261        mMainStack.activityPaused(token, false);
4262        Binder.restoreCallingIdentity(origId);
4263    }
4264
4265    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4266            CharSequence description) {
4267        if (localLOGV) Slog.v(
4268            TAG, "Activity stopped: token=" + token);
4269
4270        // Refuse possible leaked file descriptors
4271        if (icicle != null && icicle.hasFileDescriptors()) {
4272            throw new IllegalArgumentException("File descriptors passed in Bundle");
4273        }
4274
4275        ActivityRecord r = null;
4276
4277        final long origId = Binder.clearCallingIdentity();
4278
4279        synchronized (this) {
4280            r = mMainStack.isInStackLocked(token);
4281            if (r != null) {
4282                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4283            }
4284        }
4285
4286        if (r != null) {
4287            sendPendingThumbnail(r, null, null, null, false);
4288        }
4289
4290        trimApplications();
4291
4292        Binder.restoreCallingIdentity(origId);
4293    }
4294
4295    public final void activityDestroyed(IBinder token) {
4296        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4297        mMainStack.activityDestroyed(token);
4298    }
4299
4300    public String getCallingPackage(IBinder token) {
4301        synchronized (this) {
4302            ActivityRecord r = getCallingRecordLocked(token);
4303            return r != null && r.app != null ? r.info.packageName : null;
4304        }
4305    }
4306
4307    public ComponentName getCallingActivity(IBinder token) {
4308        synchronized (this) {
4309            ActivityRecord r = getCallingRecordLocked(token);
4310            return r != null ? r.intent.getComponent() : null;
4311        }
4312    }
4313
4314    private ActivityRecord getCallingRecordLocked(IBinder token) {
4315        ActivityRecord r = mMainStack.isInStackLocked(token);
4316        if (r == null) {
4317            return null;
4318        }
4319        return r.resultTo;
4320    }
4321
4322    public ComponentName getActivityClassForToken(IBinder token) {
4323        synchronized(this) {
4324            ActivityRecord r = mMainStack.isInStackLocked(token);
4325            if (r == null) {
4326                return null;
4327            }
4328            return r.intent.getComponent();
4329        }
4330    }
4331
4332    public String getPackageForToken(IBinder token) {
4333        synchronized(this) {
4334            ActivityRecord r = mMainStack.isInStackLocked(token);
4335            if (r == null) {
4336                return null;
4337            }
4338            return r.packageName;
4339        }
4340    }
4341
4342    public IIntentSender getIntentSender(int type,
4343            String packageName, IBinder token, String resultWho,
4344            int requestCode, Intent[] intents, String[] resolvedTypes,
4345            int flags, Bundle options) {
4346        enforceNotIsolatedCaller("getIntentSender");
4347        // Refuse possible leaked file descriptors
4348        if (intents != null) {
4349            if (intents.length < 1) {
4350                throw new IllegalArgumentException("Intents array length must be >= 1");
4351            }
4352            for (int i=0; i<intents.length; i++) {
4353                Intent intent = intents[i];
4354                if (intent != null) {
4355                    if (intent.hasFileDescriptors()) {
4356                        throw new IllegalArgumentException("File descriptors passed in Intent");
4357                    }
4358                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4359                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4360                        throw new IllegalArgumentException(
4361                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4362                    }
4363                    intents[i] = new Intent(intent);
4364                }
4365            }
4366            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4367                throw new IllegalArgumentException(
4368                        "Intent array length does not match resolvedTypes length");
4369            }
4370        }
4371        if (options != null) {
4372            if (options.hasFileDescriptors()) {
4373                throw new IllegalArgumentException("File descriptors passed in options");
4374            }
4375        }
4376
4377        synchronized(this) {
4378            int callingUid = Binder.getCallingUid();
4379            try {
4380                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4381                    int uid = AppGlobals.getPackageManager()
4382                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4383                    if (!UserHandle.isSameApp(callingUid, uid)) {
4384                        String msg = "Permission Denial: getIntentSender() from pid="
4385                            + Binder.getCallingPid()
4386                            + ", uid=" + Binder.getCallingUid()
4387                            + ", (need uid=" + uid + ")"
4388                            + " is not allowed to send as package " + packageName;
4389                        Slog.w(TAG, msg);
4390                        throw new SecurityException(msg);
4391                    }
4392                }
4393
4394                if (DEBUG_MU)
4395                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4396                            + Binder.getOrigCallingUid());
4397                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4398                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4399
4400            } catch (RemoteException e) {
4401                throw new SecurityException(e);
4402            }
4403        }
4404    }
4405
4406    IIntentSender getIntentSenderLocked(int type,
4407            String packageName, int callingUid, IBinder token, String resultWho,
4408            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4409            Bundle options) {
4410        if (DEBUG_MU)
4411            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4412        ActivityRecord activity = null;
4413        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4414            activity = mMainStack.isInStackLocked(token);
4415            if (activity == null) {
4416                return null;
4417            }
4418            if (activity.finishing) {
4419                return null;
4420            }
4421        }
4422
4423        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4424        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4425        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4426        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4427                |PendingIntent.FLAG_UPDATE_CURRENT);
4428
4429        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4430                type, packageName, activity, resultWho,
4431                requestCode, intents, resolvedTypes, flags, options);
4432        WeakReference<PendingIntentRecord> ref;
4433        ref = mIntentSenderRecords.get(key);
4434        PendingIntentRecord rec = ref != null ? ref.get() : null;
4435        if (rec != null) {
4436            if (!cancelCurrent) {
4437                if (updateCurrent) {
4438                    if (rec.key.requestIntent != null) {
4439                        rec.key.requestIntent.replaceExtras(intents != null ?
4440                                intents[intents.length - 1] : null);
4441                    }
4442                    if (intents != null) {
4443                        intents[intents.length-1] = rec.key.requestIntent;
4444                        rec.key.allIntents = intents;
4445                        rec.key.allResolvedTypes = resolvedTypes;
4446                    } else {
4447                        rec.key.allIntents = null;
4448                        rec.key.allResolvedTypes = null;
4449                    }
4450                }
4451                return rec;
4452            }
4453            rec.canceled = true;
4454            mIntentSenderRecords.remove(key);
4455        }
4456        if (noCreate) {
4457            return rec;
4458        }
4459        rec = new PendingIntentRecord(this, key, callingUid);
4460        mIntentSenderRecords.put(key, rec.ref);
4461        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4462            if (activity.pendingResults == null) {
4463                activity.pendingResults
4464                        = new HashSet<WeakReference<PendingIntentRecord>>();
4465            }
4466            activity.pendingResults.add(rec.ref);
4467        }
4468        return rec;
4469    }
4470
4471    public void cancelIntentSender(IIntentSender sender) {
4472        if (!(sender instanceof PendingIntentRecord)) {
4473            return;
4474        }
4475        synchronized(this) {
4476            PendingIntentRecord rec = (PendingIntentRecord)sender;
4477            try {
4478                int uid = AppGlobals.getPackageManager()
4479                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4480                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4481                    String msg = "Permission Denial: cancelIntentSender() from pid="
4482                        + Binder.getCallingPid()
4483                        + ", uid=" + Binder.getCallingUid()
4484                        + " is not allowed to cancel packges "
4485                        + rec.key.packageName;
4486                    Slog.w(TAG, msg);
4487                    throw new SecurityException(msg);
4488                }
4489            } catch (RemoteException e) {
4490                throw new SecurityException(e);
4491            }
4492            cancelIntentSenderLocked(rec, true);
4493        }
4494    }
4495
4496    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4497        rec.canceled = true;
4498        mIntentSenderRecords.remove(rec.key);
4499        if (cleanActivity && rec.key.activity != null) {
4500            rec.key.activity.pendingResults.remove(rec.ref);
4501        }
4502    }
4503
4504    public String getPackageForIntentSender(IIntentSender pendingResult) {
4505        if (!(pendingResult instanceof PendingIntentRecord)) {
4506            return null;
4507        }
4508        try {
4509            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4510            return res.key.packageName;
4511        } catch (ClassCastException e) {
4512        }
4513        return null;
4514    }
4515
4516    public int getUidForIntentSender(IIntentSender sender) {
4517        if (sender instanceof PendingIntentRecord) {
4518            try {
4519                PendingIntentRecord res = (PendingIntentRecord)sender;
4520                return res.uid;
4521            } catch (ClassCastException e) {
4522            }
4523        }
4524        return -1;
4525    }
4526
4527    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4528        if (!(pendingResult instanceof PendingIntentRecord)) {
4529            return false;
4530        }
4531        try {
4532            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4533            if (res.key.allIntents == null) {
4534                return false;
4535            }
4536            for (int i=0; i<res.key.allIntents.length; i++) {
4537                Intent intent = res.key.allIntents[i];
4538                if (intent.getPackage() != null && intent.getComponent() != null) {
4539                    return false;
4540                }
4541            }
4542            return true;
4543        } catch (ClassCastException e) {
4544        }
4545        return false;
4546    }
4547
4548    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4549        if (!(pendingResult instanceof PendingIntentRecord)) {
4550            return false;
4551        }
4552        try {
4553            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4554            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4555                return true;
4556            }
4557            return false;
4558        } catch (ClassCastException e) {
4559        }
4560        return false;
4561    }
4562
4563    public void setProcessLimit(int max) {
4564        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4565                "setProcessLimit()");
4566        synchronized (this) {
4567            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4568            mProcessLimitOverride = max;
4569        }
4570        trimApplications();
4571    }
4572
4573    public int getProcessLimit() {
4574        synchronized (this) {
4575            return mProcessLimitOverride;
4576        }
4577    }
4578
4579    void foregroundTokenDied(ForegroundToken token) {
4580        synchronized (ActivityManagerService.this) {
4581            synchronized (mPidsSelfLocked) {
4582                ForegroundToken cur
4583                    = mForegroundProcesses.get(token.pid);
4584                if (cur != token) {
4585                    return;
4586                }
4587                mForegroundProcesses.remove(token.pid);
4588                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4589                if (pr == null) {
4590                    return;
4591                }
4592                pr.forcingToForeground = null;
4593                pr.foregroundServices = false;
4594            }
4595            updateOomAdjLocked();
4596        }
4597    }
4598
4599    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4600        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4601                "setProcessForeground()");
4602        synchronized(this) {
4603            boolean changed = false;
4604
4605            synchronized (mPidsSelfLocked) {
4606                ProcessRecord pr = mPidsSelfLocked.get(pid);
4607                if (pr == null && isForeground) {
4608                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4609                    return;
4610                }
4611                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4612                if (oldToken != null) {
4613                    oldToken.token.unlinkToDeath(oldToken, 0);
4614                    mForegroundProcesses.remove(pid);
4615                    if (pr != null) {
4616                        pr.forcingToForeground = null;
4617                    }
4618                    changed = true;
4619                }
4620                if (isForeground && token != null) {
4621                    ForegroundToken newToken = new ForegroundToken() {
4622                        public void binderDied() {
4623                            foregroundTokenDied(this);
4624                        }
4625                    };
4626                    newToken.pid = pid;
4627                    newToken.token = token;
4628                    try {
4629                        token.linkToDeath(newToken, 0);
4630                        mForegroundProcesses.put(pid, newToken);
4631                        pr.forcingToForeground = token;
4632                        changed = true;
4633                    } catch (RemoteException e) {
4634                        // If the process died while doing this, we will later
4635                        // do the cleanup with the process death link.
4636                    }
4637                }
4638            }
4639
4640            if (changed) {
4641                updateOomAdjLocked();
4642            }
4643        }
4644    }
4645
4646    // =========================================================
4647    // PERMISSIONS
4648    // =========================================================
4649
4650    static class PermissionController extends IPermissionController.Stub {
4651        ActivityManagerService mActivityManagerService;
4652        PermissionController(ActivityManagerService activityManagerService) {
4653            mActivityManagerService = activityManagerService;
4654        }
4655
4656        public boolean checkPermission(String permission, int pid, int uid) {
4657            return mActivityManagerService.checkPermission(permission, pid,
4658                    uid) == PackageManager.PERMISSION_GRANTED;
4659        }
4660    }
4661
4662    /**
4663     * This can be called with or without the global lock held.
4664     */
4665    int checkComponentPermission(String permission, int pid, int uid,
4666            int owningUid, boolean exported) {
4667        // We might be performing an operation on behalf of an indirect binder
4668        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4669        // client identity accordingly before proceeding.
4670        Identity tlsIdentity = sCallerIdentity.get();
4671        if (tlsIdentity != null) {
4672            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4673                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4674            uid = tlsIdentity.uid;
4675            pid = tlsIdentity.pid;
4676        }
4677
4678        if (pid == MY_PID) {
4679            return PackageManager.PERMISSION_GRANTED;
4680        }
4681
4682        return ActivityManager.checkComponentPermission(permission, uid,
4683                owningUid, exported);
4684    }
4685
4686    /**
4687     * As the only public entry point for permissions checking, this method
4688     * can enforce the semantic that requesting a check on a null global
4689     * permission is automatically denied.  (Internally a null permission
4690     * string is used when calling {@link #checkComponentPermission} in cases
4691     * when only uid-based security is needed.)
4692     *
4693     * This can be called with or without the global lock held.
4694     */
4695    public int checkPermission(String permission, int pid, int uid) {
4696        if (permission == null) {
4697            return PackageManager.PERMISSION_DENIED;
4698        }
4699        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4700    }
4701
4702    /**
4703     * Binder IPC calls go through the public entry point.
4704     * This can be called with or without the global lock held.
4705     */
4706    int checkCallingPermission(String permission) {
4707        return checkPermission(permission,
4708                Binder.getCallingPid(),
4709                UserHandle.getAppId(Binder.getCallingUid()));
4710    }
4711
4712    /**
4713     * This can be called with or without the global lock held.
4714     */
4715    void enforceCallingPermission(String permission, String func) {
4716        if (checkCallingPermission(permission)
4717                == PackageManager.PERMISSION_GRANTED) {
4718            return;
4719        }
4720
4721        String msg = "Permission Denial: " + func + " from pid="
4722                + Binder.getCallingPid()
4723                + ", uid=" + Binder.getCallingUid()
4724                + " requires " + permission;
4725        Slog.w(TAG, msg);
4726        throw new SecurityException(msg);
4727    }
4728
4729    /**
4730     * Determine if UID is holding permissions required to access {@link Uri} in
4731     * the given {@link ProviderInfo}. Final permission checking is always done
4732     * in {@link ContentProvider}.
4733     */
4734    private final boolean checkHoldingPermissionsLocked(
4735            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4736        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4737                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4738
4739        if (pi.applicationInfo.uid == uid) {
4740            return true;
4741        } else if (!pi.exported) {
4742            return false;
4743        }
4744
4745        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4746        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4747        try {
4748            // check if target holds top-level <provider> permissions
4749            if (!readMet && pi.readPermission != null
4750                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4751                readMet = true;
4752            }
4753            if (!writeMet && pi.writePermission != null
4754                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4755                writeMet = true;
4756            }
4757
4758            // track if unprotected read/write is allowed; any denied
4759            // <path-permission> below removes this ability
4760            boolean allowDefaultRead = pi.readPermission == null;
4761            boolean allowDefaultWrite = pi.writePermission == null;
4762
4763            // check if target holds any <path-permission> that match uri
4764            final PathPermission[] pps = pi.pathPermissions;
4765            if (pps != null) {
4766                final String path = uri.getPath();
4767                int i = pps.length;
4768                while (i > 0 && (!readMet || !writeMet)) {
4769                    i--;
4770                    PathPermission pp = pps[i];
4771                    if (pp.match(path)) {
4772                        if (!readMet) {
4773                            final String pprperm = pp.getReadPermission();
4774                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4775                                    + pprperm + " for " + pp.getPath()
4776                                    + ": match=" + pp.match(path)
4777                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4778                            if (pprperm != null) {
4779                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4780                                    readMet = true;
4781                                } else {
4782                                    allowDefaultRead = false;
4783                                }
4784                            }
4785                        }
4786                        if (!writeMet) {
4787                            final String ppwperm = pp.getWritePermission();
4788                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4789                                    + ppwperm + " for " + pp.getPath()
4790                                    + ": match=" + pp.match(path)
4791                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4792                            if (ppwperm != null) {
4793                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4794                                    writeMet = true;
4795                                } else {
4796                                    allowDefaultWrite = false;
4797                                }
4798                            }
4799                        }
4800                    }
4801                }
4802            }
4803
4804            // grant unprotected <provider> read/write, if not blocked by
4805            // <path-permission> above
4806            if (allowDefaultRead) readMet = true;
4807            if (allowDefaultWrite) writeMet = true;
4808
4809        } catch (RemoteException e) {
4810            return false;
4811        }
4812
4813        return readMet && writeMet;
4814    }
4815
4816    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4817            int modeFlags) {
4818        // Root gets to do everything.
4819        if (uid == 0) {
4820            return true;
4821        }
4822        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4823        if (perms == null) return false;
4824        UriPermission perm = perms.get(uri);
4825        if (perm == null) return false;
4826        return (modeFlags&perm.modeFlags) == modeFlags;
4827    }
4828
4829    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4830        enforceNotIsolatedCaller("checkUriPermission");
4831
4832        // Another redirected-binder-call permissions check as in
4833        // {@link checkComponentPermission}.
4834        Identity tlsIdentity = sCallerIdentity.get();
4835        if (tlsIdentity != null) {
4836            uid = tlsIdentity.uid;
4837            pid = tlsIdentity.pid;
4838        }
4839
4840        uid = UserHandle.getAppId(uid);
4841        // Our own process gets to do everything.
4842        if (pid == MY_PID) {
4843            return PackageManager.PERMISSION_GRANTED;
4844        }
4845        synchronized(this) {
4846            return checkUriPermissionLocked(uri, uid, modeFlags)
4847                    ? PackageManager.PERMISSION_GRANTED
4848                    : PackageManager.PERMISSION_DENIED;
4849        }
4850    }
4851
4852    /**
4853     * Check if the targetPkg can be granted permission to access uri by
4854     * the callingUid using the given modeFlags.  Throws a security exception
4855     * if callingUid is not allowed to do this.  Returns the uid of the target
4856     * if the URI permission grant should be performed; returns -1 if it is not
4857     * needed (for example targetPkg already has permission to access the URI).
4858     * If you already know the uid of the target, you can supply it in
4859     * lastTargetUid else set that to -1.
4860     */
4861    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4862            Uri uri, int modeFlags, int lastTargetUid) {
4863        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4864                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4865        if (modeFlags == 0) {
4866            return -1;
4867        }
4868
4869        if (targetPkg != null) {
4870            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4871                    "Checking grant " + targetPkg + " permission to " + uri);
4872        }
4873
4874        final IPackageManager pm = AppGlobals.getPackageManager();
4875
4876        // If this is not a content: uri, we can't do anything with it.
4877        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4878            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4879                    "Can't grant URI permission for non-content URI: " + uri);
4880            return -1;
4881        }
4882
4883        String name = uri.getAuthority();
4884        ProviderInfo pi = null;
4885        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4886                UserHandle.getUserId(callingUid));
4887        if (cpr != null) {
4888            pi = cpr.info;
4889        } else {
4890            try {
4891                pi = pm.resolveContentProvider(name,
4892                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4893            } catch (RemoteException ex) {
4894            }
4895        }
4896        if (pi == null) {
4897            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4898            return -1;
4899        }
4900
4901        int targetUid = lastTargetUid;
4902        if (targetUid < 0 && targetPkg != null) {
4903            try {
4904                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4905                if (targetUid < 0) {
4906                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4907                            "Can't grant URI permission no uid for: " + targetPkg);
4908                    return -1;
4909                }
4910            } catch (RemoteException ex) {
4911                return -1;
4912            }
4913        }
4914
4915        if (targetUid >= 0) {
4916            // First...  does the target actually need this permission?
4917            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4918                // No need to grant the target this permission.
4919                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4920                        "Target " + targetPkg + " already has full permission to " + uri);
4921                return -1;
4922            }
4923        } else {
4924            // First...  there is no target package, so can anyone access it?
4925            boolean allowed = pi.exported;
4926            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4927                if (pi.readPermission != null) {
4928                    allowed = false;
4929                }
4930            }
4931            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4932                if (pi.writePermission != null) {
4933                    allowed = false;
4934                }
4935            }
4936            if (allowed) {
4937                return -1;
4938            }
4939        }
4940
4941        // Second...  is the provider allowing granting of URI permissions?
4942        if (!pi.grantUriPermissions) {
4943            throw new SecurityException("Provider " + pi.packageName
4944                    + "/" + pi.name
4945                    + " does not allow granting of Uri permissions (uri "
4946                    + uri + ")");
4947        }
4948        if (pi.uriPermissionPatterns != null) {
4949            final int N = pi.uriPermissionPatterns.length;
4950            boolean allowed = false;
4951            for (int i=0; i<N; i++) {
4952                if (pi.uriPermissionPatterns[i] != null
4953                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4954                    allowed = true;
4955                    break;
4956                }
4957            }
4958            if (!allowed) {
4959                throw new SecurityException("Provider " + pi.packageName
4960                        + "/" + pi.name
4961                        + " does not allow granting of permission to path of Uri "
4962                        + uri);
4963            }
4964        }
4965
4966        // Third...  does the caller itself have permission to access
4967        // this uri?
4968        if (callingUid != Process.myUid()) {
4969            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4970                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4971                    throw new SecurityException("Uid " + callingUid
4972                            + " does not have permission to uri " + uri);
4973                }
4974            }
4975        }
4976
4977        return targetUid;
4978    }
4979
4980    public int checkGrantUriPermission(int callingUid, String targetPkg,
4981            Uri uri, int modeFlags) {
4982        enforceNotIsolatedCaller("checkGrantUriPermission");
4983        synchronized(this) {
4984            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4985        }
4986    }
4987
4988    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4989            Uri uri, int modeFlags, UriPermissionOwner owner) {
4990        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4991                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4992        if (modeFlags == 0) {
4993            return;
4994        }
4995
4996        // So here we are: the caller has the assumed permission
4997        // to the uri, and the target doesn't.  Let's now give this to
4998        // the target.
4999
5000        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5001                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5002
5003        HashMap<Uri, UriPermission> targetUris
5004                = mGrantedUriPermissions.get(targetUid);
5005        if (targetUris == null) {
5006            targetUris = new HashMap<Uri, UriPermission>();
5007            mGrantedUriPermissions.put(targetUid, targetUris);
5008        }
5009
5010        UriPermission perm = targetUris.get(uri);
5011        if (perm == null) {
5012            perm = new UriPermission(targetUid, uri);
5013            targetUris.put(uri, perm);
5014        }
5015
5016        perm.modeFlags |= modeFlags;
5017        if (owner == null) {
5018            perm.globalModeFlags |= modeFlags;
5019        } else {
5020            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5021                 perm.readOwners.add(owner);
5022                 owner.addReadPermission(perm);
5023            }
5024            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5025                 perm.writeOwners.add(owner);
5026                 owner.addWritePermission(perm);
5027            }
5028        }
5029    }
5030
5031    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5032            int modeFlags, UriPermissionOwner owner) {
5033        if (targetPkg == null) {
5034            throw new NullPointerException("targetPkg");
5035        }
5036
5037        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5038        if (targetUid < 0) {
5039            return;
5040        }
5041
5042        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5043    }
5044
5045    static class NeededUriGrants extends ArrayList<Uri> {
5046        final String targetPkg;
5047        final int targetUid;
5048        final int flags;
5049
5050        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5051            targetPkg = _targetPkg;
5052            targetUid = _targetUid;
5053            flags = _flags;
5054        }
5055    }
5056
5057    /**
5058     * Like checkGrantUriPermissionLocked, but takes an Intent.
5059     */
5060    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5061            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5062        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5063                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5064                + " clip=" + (intent != null ? intent.getClipData() : null)
5065                + " from " + intent + "; flags=0x"
5066                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5067
5068        if (targetPkg == null) {
5069            throw new NullPointerException("targetPkg");
5070        }
5071
5072        if (intent == null) {
5073            return null;
5074        }
5075        Uri data = intent.getData();
5076        ClipData clip = intent.getClipData();
5077        if (data == null && clip == null) {
5078            return null;
5079        }
5080        if (data != null) {
5081            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5082                mode, needed != null ? needed.targetUid : -1);
5083            if (target > 0) {
5084                if (needed == null) {
5085                    needed = new NeededUriGrants(targetPkg, target, mode);
5086                }
5087                needed.add(data);
5088            }
5089        }
5090        if (clip != null) {
5091            for (int i=0; i<clip.getItemCount(); i++) {
5092                Uri uri = clip.getItemAt(i).getUri();
5093                if (uri != null) {
5094                    int target = -1;
5095                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5096                            mode, needed != null ? needed.targetUid : -1);
5097                    if (target > 0) {
5098                        if (needed == null) {
5099                            needed = new NeededUriGrants(targetPkg, target, mode);
5100                        }
5101                        needed.add(uri);
5102                    }
5103                } else {
5104                    Intent clipIntent = clip.getItemAt(i).getIntent();
5105                    if (clipIntent != null) {
5106                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5107                                callingUid, targetPkg, clipIntent, mode, needed);
5108                        if (newNeeded != null) {
5109                            needed = newNeeded;
5110                        }
5111                    }
5112                }
5113            }
5114        }
5115
5116        return needed;
5117    }
5118
5119    /**
5120     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5121     */
5122    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5123            UriPermissionOwner owner) {
5124        if (needed != null) {
5125            for (int i=0; i<needed.size(); i++) {
5126                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5127                        needed.get(i), needed.flags, owner);
5128            }
5129        }
5130    }
5131
5132    void grantUriPermissionFromIntentLocked(int callingUid,
5133            String targetPkg, Intent intent, UriPermissionOwner owner) {
5134        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5135                intent, intent != null ? intent.getFlags() : 0, null);
5136        if (needed == null) {
5137            return;
5138        }
5139
5140        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5141    }
5142
5143    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5144            Uri uri, int modeFlags) {
5145        enforceNotIsolatedCaller("grantUriPermission");
5146        synchronized(this) {
5147            final ProcessRecord r = getRecordForAppLocked(caller);
5148            if (r == null) {
5149                throw new SecurityException("Unable to find app for caller "
5150                        + caller
5151                        + " when granting permission to uri " + uri);
5152            }
5153            if (targetPkg == null) {
5154                throw new IllegalArgumentException("null target");
5155            }
5156            if (uri == null) {
5157                throw new IllegalArgumentException("null uri");
5158            }
5159
5160            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5161                    null);
5162        }
5163    }
5164
5165    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5166        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5167                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5168            HashMap<Uri, UriPermission> perms
5169                    = mGrantedUriPermissions.get(perm.uid);
5170            if (perms != null) {
5171                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5172                        "Removing " + perm.uid + " permission to " + perm.uri);
5173                perms.remove(perm.uri);
5174                if (perms.size() == 0) {
5175                    mGrantedUriPermissions.remove(perm.uid);
5176                }
5177            }
5178        }
5179    }
5180
5181    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5182            int modeFlags) {
5183        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5184                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5185        if (modeFlags == 0) {
5186            return;
5187        }
5188
5189        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5190                "Revoking all granted permissions to " + uri);
5191
5192        final IPackageManager pm = AppGlobals.getPackageManager();
5193
5194        final String authority = uri.getAuthority();
5195        ProviderInfo pi = null;
5196        int userId = UserHandle.getUserId(callingUid);
5197        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5198        if (cpr != null) {
5199            pi = cpr.info;
5200        } else {
5201            try {
5202                pi = pm.resolveContentProvider(authority,
5203                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5204            } catch (RemoteException ex) {
5205            }
5206        }
5207        if (pi == null) {
5208            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5209            return;
5210        }
5211
5212        // Does the caller have this permission on the URI?
5213        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5214            // Right now, if you are not the original owner of the permission,
5215            // you are not allowed to revoke it.
5216            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5217                throw new SecurityException("Uid " + callingUid
5218                        + " does not have permission to uri " + uri);
5219            //}
5220        }
5221
5222        // Go through all of the permissions and remove any that match.
5223        final List<String> SEGMENTS = uri.getPathSegments();
5224        if (SEGMENTS != null) {
5225            final int NS = SEGMENTS.size();
5226            int N = mGrantedUriPermissions.size();
5227            for (int i=0; i<N; i++) {
5228                HashMap<Uri, UriPermission> perms
5229                        = mGrantedUriPermissions.valueAt(i);
5230                Iterator<UriPermission> it = perms.values().iterator();
5231            toploop:
5232                while (it.hasNext()) {
5233                    UriPermission perm = it.next();
5234                    Uri targetUri = perm.uri;
5235                    if (!authority.equals(targetUri.getAuthority())) {
5236                        continue;
5237                    }
5238                    List<String> targetSegments = targetUri.getPathSegments();
5239                    if (targetSegments == null) {
5240                        continue;
5241                    }
5242                    if (targetSegments.size() < NS) {
5243                        continue;
5244                    }
5245                    for (int j=0; j<NS; j++) {
5246                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5247                            continue toploop;
5248                        }
5249                    }
5250                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5251                            "Revoking " + perm.uid + " permission to " + perm.uri);
5252                    perm.clearModes(modeFlags);
5253                    if (perm.modeFlags == 0) {
5254                        it.remove();
5255                    }
5256                }
5257                if (perms.size() == 0) {
5258                    mGrantedUriPermissions.remove(
5259                            mGrantedUriPermissions.keyAt(i));
5260                    N--;
5261                    i--;
5262                }
5263            }
5264        }
5265    }
5266
5267    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5268            int modeFlags) {
5269        enforceNotIsolatedCaller("revokeUriPermission");
5270        synchronized(this) {
5271            final ProcessRecord r = getRecordForAppLocked(caller);
5272            if (r == null) {
5273                throw new SecurityException("Unable to find app for caller "
5274                        + caller
5275                        + " when revoking permission to uri " + uri);
5276            }
5277            if (uri == null) {
5278                Slog.w(TAG, "revokeUriPermission: null uri");
5279                return;
5280            }
5281
5282            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5283                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5284            if (modeFlags == 0) {
5285                return;
5286            }
5287
5288            final IPackageManager pm = AppGlobals.getPackageManager();
5289
5290            final String authority = uri.getAuthority();
5291            ProviderInfo pi = null;
5292            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5293            if (cpr != null) {
5294                pi = cpr.info;
5295            } else {
5296                try {
5297                    pi = pm.resolveContentProvider(authority,
5298                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5299                } catch (RemoteException ex) {
5300                }
5301            }
5302            if (pi == null) {
5303                Slog.w(TAG, "No content provider found for permission revoke: "
5304                        + uri.toSafeString());
5305                return;
5306            }
5307
5308            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5309        }
5310    }
5311
5312    @Override
5313    public IBinder newUriPermissionOwner(String name) {
5314        enforceNotIsolatedCaller("newUriPermissionOwner");
5315        synchronized(this) {
5316            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5317            return owner.getExternalTokenLocked();
5318        }
5319    }
5320
5321    @Override
5322    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5323            Uri uri, int modeFlags) {
5324        synchronized(this) {
5325            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5326            if (owner == null) {
5327                throw new IllegalArgumentException("Unknown owner: " + token);
5328            }
5329            if (fromUid != Binder.getCallingUid()) {
5330                if (Binder.getCallingUid() != Process.myUid()) {
5331                    // Only system code can grant URI permissions on behalf
5332                    // of other users.
5333                    throw new SecurityException("nice try");
5334                }
5335            }
5336            if (targetPkg == null) {
5337                throw new IllegalArgumentException("null target");
5338            }
5339            if (uri == null) {
5340                throw new IllegalArgumentException("null uri");
5341            }
5342
5343            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5344        }
5345    }
5346
5347    @Override
5348    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5349        synchronized(this) {
5350            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5351            if (owner == null) {
5352                throw new IllegalArgumentException("Unknown owner: " + token);
5353            }
5354
5355            if (uri == null) {
5356                owner.removeUriPermissionsLocked(mode);
5357            } else {
5358                owner.removeUriPermissionLocked(uri, mode);
5359            }
5360        }
5361    }
5362
5363    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5364        synchronized (this) {
5365            ProcessRecord app =
5366                who != null ? getRecordForAppLocked(who) : null;
5367            if (app == null) return;
5368
5369            Message msg = Message.obtain();
5370            msg.what = WAIT_FOR_DEBUGGER_MSG;
5371            msg.obj = app;
5372            msg.arg1 = waiting ? 1 : 0;
5373            mHandler.sendMessage(msg);
5374        }
5375    }
5376
5377    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5378        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5379        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5380        outInfo.availMem = Process.getFreeMemory();
5381        outInfo.totalMem = Process.getTotalMemory();
5382        outInfo.threshold = homeAppMem;
5383        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5384        outInfo.hiddenAppThreshold = hiddenAppMem;
5385        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5386                ProcessList.SERVICE_ADJ);
5387        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5388                ProcessList.VISIBLE_APP_ADJ);
5389        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5390                ProcessList.FOREGROUND_APP_ADJ);
5391    }
5392
5393    // =========================================================
5394    // TASK MANAGEMENT
5395    // =========================================================
5396
5397    public List getTasks(int maxNum, int flags,
5398                         IThumbnailReceiver receiver) {
5399        ArrayList list = new ArrayList();
5400
5401        PendingThumbnailsRecord pending = null;
5402        IApplicationThread topThumbnail = null;
5403        ActivityRecord topRecord = null;
5404
5405        synchronized(this) {
5406            if (localLOGV) Slog.v(
5407                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5408                + ", receiver=" + receiver);
5409
5410            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5411                    != PackageManager.PERMISSION_GRANTED) {
5412                if (receiver != null) {
5413                    // If the caller wants to wait for pending thumbnails,
5414                    // it ain't gonna get them.
5415                    try {
5416                        receiver.finished();
5417                    } catch (RemoteException ex) {
5418                    }
5419                }
5420                String msg = "Permission Denial: getTasks() from pid="
5421                        + Binder.getCallingPid()
5422                        + ", uid=" + Binder.getCallingUid()
5423                        + " requires " + android.Manifest.permission.GET_TASKS;
5424                Slog.w(TAG, msg);
5425                throw new SecurityException(msg);
5426            }
5427
5428            int pos = mMainStack.mHistory.size()-1;
5429            ActivityRecord next =
5430                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5431            ActivityRecord top = null;
5432            TaskRecord curTask = null;
5433            int numActivities = 0;
5434            int numRunning = 0;
5435            while (pos >= 0 && maxNum > 0) {
5436                final ActivityRecord r = next;
5437                pos--;
5438                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5439
5440                // Initialize state for next task if needed.
5441                if (top == null ||
5442                        (top.state == ActivityState.INITIALIZING
5443                            && top.task == r.task)) {
5444                    top = r;
5445                    curTask = r.task;
5446                    numActivities = numRunning = 0;
5447                }
5448
5449                // Add 'r' into the current task.
5450                numActivities++;
5451                if (r.app != null && r.app.thread != null) {
5452                    numRunning++;
5453                }
5454
5455                if (localLOGV) Slog.v(
5456                    TAG, r.intent.getComponent().flattenToShortString()
5457                    + ": task=" + r.task);
5458
5459                // If the next one is a different task, generate a new
5460                // TaskInfo entry for what we have.
5461                if (next == null || next.task != curTask) {
5462                    ActivityManager.RunningTaskInfo ci
5463                            = new ActivityManager.RunningTaskInfo();
5464                    ci.id = curTask.taskId;
5465                    ci.baseActivity = r.intent.getComponent();
5466                    ci.topActivity = top.intent.getComponent();
5467                    if (top.thumbHolder != null) {
5468                        ci.description = top.thumbHolder.lastDescription;
5469                    }
5470                    ci.numActivities = numActivities;
5471                    ci.numRunning = numRunning;
5472                    //System.out.println(
5473                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5474                    if (ci.thumbnail == null && receiver != null) {
5475                        if (localLOGV) Slog.v(
5476                            TAG, "State=" + top.state + "Idle=" + top.idle
5477                            + " app=" + top.app
5478                            + " thr=" + (top.app != null ? top.app.thread : null));
5479                        if (top.state == ActivityState.RESUMED
5480                                || top.state == ActivityState.PAUSING) {
5481                            if (top.idle && top.app != null
5482                                && top.app.thread != null) {
5483                                topRecord = top;
5484                                topThumbnail = top.app.thread;
5485                            } else {
5486                                top.thumbnailNeeded = true;
5487                            }
5488                        }
5489                        if (pending == null) {
5490                            pending = new PendingThumbnailsRecord(receiver);
5491                        }
5492                        pending.pendingRecords.add(top);
5493                    }
5494                    list.add(ci);
5495                    maxNum--;
5496                    top = null;
5497                }
5498            }
5499
5500            if (pending != null) {
5501                mPendingThumbnails.add(pending);
5502            }
5503        }
5504
5505        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5506
5507        if (topThumbnail != null) {
5508            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5509            try {
5510                topThumbnail.requestThumbnail(topRecord.appToken);
5511            } catch (Exception e) {
5512                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5513                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5514            }
5515        }
5516
5517        if (pending == null && receiver != null) {
5518            // In this case all thumbnails were available and the client
5519            // is being asked to be told when the remaining ones come in...
5520            // which is unusually, since the top-most currently running
5521            // activity should never have a canned thumbnail!  Oh well.
5522            try {
5523                receiver.finished();
5524            } catch (RemoteException ex) {
5525            }
5526        }
5527
5528        return list;
5529    }
5530
5531    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5532            int flags, int userId) {
5533        final int callingUid = Binder.getCallingUid();
5534        if (userId != UserHandle.getCallingUserId()) {
5535            // Check if the caller is holding permissions for cross-user requests.
5536            if (checkComponentPermission(
5537                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5538                    Binder.getCallingPid(), callingUid, -1, true)
5539                    != PackageManager.PERMISSION_GRANTED) {
5540                String msg = "Permission Denial: "
5541                        + "Request to get recent tasks for user " + userId
5542                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5543                        + "; this requires "
5544                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5545                Slog.w(TAG, msg);
5546                throw new SecurityException(msg);
5547            } else {
5548                if (userId == UserHandle.USER_CURRENT) {
5549                    userId = mCurrentUserId;
5550                }
5551            }
5552        }
5553
5554        synchronized (this) {
5555            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5556                    "getRecentTasks()");
5557            final boolean detailed = checkCallingPermission(
5558                    android.Manifest.permission.GET_DETAILED_TASKS)
5559                    == PackageManager.PERMISSION_GRANTED;
5560
5561            IPackageManager pm = AppGlobals.getPackageManager();
5562
5563            final int N = mRecentTasks.size();
5564            ArrayList<ActivityManager.RecentTaskInfo> res
5565                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5566                            maxNum < N ? maxNum : N);
5567            for (int i=0; i<N && maxNum > 0; i++) {
5568                TaskRecord tr = mRecentTasks.get(i);
5569                // Only add calling user's recent tasks
5570                if (tr.userId != userId) continue;
5571                // Return the entry if desired by the caller.  We always return
5572                // the first entry, because callers always expect this to be the
5573                // foreground app.  We may filter others if the caller has
5574                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5575                // we should exclude the entry.
5576
5577                if (i == 0
5578                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5579                        || (tr.intent == null)
5580                        || ((tr.intent.getFlags()
5581                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5582                    ActivityManager.RecentTaskInfo rti
5583                            = new ActivityManager.RecentTaskInfo();
5584                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5585                    rti.persistentId = tr.taskId;
5586                    rti.baseIntent = new Intent(
5587                            tr.intent != null ? tr.intent : tr.affinityIntent);
5588                    if (!detailed) {
5589                        rti.baseIntent.replaceExtras((Bundle)null);
5590                    }
5591                    rti.origActivity = tr.origActivity;
5592                    rti.description = tr.lastDescription;
5593
5594                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5595                        // Check whether this activity is currently available.
5596                        try {
5597                            if (rti.origActivity != null) {
5598                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5599                                        == null) {
5600                                    continue;
5601                                }
5602                            } else if (rti.baseIntent != null) {
5603                                if (pm.queryIntentActivities(rti.baseIntent,
5604                                        null, 0, userId) == null) {
5605                                    continue;
5606                                }
5607                            }
5608                        } catch (RemoteException e) {
5609                            // Will never happen.
5610                        }
5611                    }
5612
5613                    res.add(rti);
5614                    maxNum--;
5615                }
5616            }
5617            return res;
5618        }
5619    }
5620
5621    private TaskRecord taskForIdLocked(int id) {
5622        final int N = mRecentTasks.size();
5623        for (int i=0; i<N; i++) {
5624            TaskRecord tr = mRecentTasks.get(i);
5625            if (tr.taskId == id) {
5626                return tr;
5627            }
5628        }
5629        return null;
5630    }
5631
5632    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5633        synchronized (this) {
5634            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5635                    "getTaskThumbnails()");
5636            TaskRecord tr = taskForIdLocked(id);
5637            if (tr != null) {
5638                return mMainStack.getTaskThumbnailsLocked(tr);
5639            }
5640        }
5641        return null;
5642    }
5643
5644    public boolean removeSubTask(int taskId, int subTaskIndex) {
5645        synchronized (this) {
5646            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5647                    "removeSubTask()");
5648            long ident = Binder.clearCallingIdentity();
5649            try {
5650                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5651                        true) != null;
5652            } finally {
5653                Binder.restoreCallingIdentity(ident);
5654            }
5655        }
5656    }
5657
5658    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5659        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5660        Intent baseIntent = new Intent(
5661                tr.intent != null ? tr.intent : tr.affinityIntent);
5662        ComponentName component = baseIntent.getComponent();
5663        if (component == null) {
5664            Slog.w(TAG, "Now component for base intent of task: " + tr);
5665            return;
5666        }
5667
5668        // Find any running services associated with this app.
5669        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5670
5671        if (killProcesses) {
5672            // Find any running processes associated with this app.
5673            final String pkg = component.getPackageName();
5674            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5675            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5676            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5677                for (int i=0; i<uids.size(); i++) {
5678                    ProcessRecord proc = uids.valueAt(i);
5679                    if (proc.userId != tr.userId) {
5680                        continue;
5681                    }
5682                    if (!proc.pkgList.contains(pkg)) {
5683                        continue;
5684                    }
5685                    procs.add(proc);
5686                }
5687            }
5688
5689            // Kill the running processes.
5690            for (int i=0; i<procs.size(); i++) {
5691                ProcessRecord pr = procs.get(i);
5692                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5693                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5694                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5695                            pr.processName, pr.setAdj, "remove task");
5696                    pr.killedBackground = true;
5697                    Process.killProcessQuiet(pr.pid);
5698                } else {
5699                    pr.waitingToKill = "remove task";
5700                }
5701            }
5702        }
5703    }
5704
5705    public boolean removeTask(int taskId, int flags) {
5706        synchronized (this) {
5707            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5708                    "removeTask()");
5709            long ident = Binder.clearCallingIdentity();
5710            try {
5711                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5712                        false);
5713                if (r != null) {
5714                    mRecentTasks.remove(r.task);
5715                    cleanUpRemovedTaskLocked(r.task, flags);
5716                    return true;
5717                } else {
5718                    TaskRecord tr = null;
5719                    int i=0;
5720                    while (i < mRecentTasks.size()) {
5721                        TaskRecord t = mRecentTasks.get(i);
5722                        if (t.taskId == taskId) {
5723                            tr = t;
5724                            break;
5725                        }
5726                        i++;
5727                    }
5728                    if (tr != null) {
5729                        if (tr.numActivities <= 0) {
5730                            // Caller is just removing a recent task that is
5731                            // not actively running.  That is easy!
5732                            mRecentTasks.remove(i);
5733                            cleanUpRemovedTaskLocked(tr, flags);
5734                            return true;
5735                        } else {
5736                            Slog.w(TAG, "removeTask: task " + taskId
5737                                    + " does not have activities to remove, "
5738                                    + " but numActivities=" + tr.numActivities
5739                                    + ": " + tr);
5740                        }
5741                    }
5742                }
5743            } finally {
5744                Binder.restoreCallingIdentity(ident);
5745            }
5746        }
5747        return false;
5748    }
5749
5750    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5751        int j;
5752        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5753        TaskRecord jt = startTask;
5754
5755        // First look backwards
5756        for (j=startIndex-1; j>=0; j--) {
5757            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5758            if (r.task != jt) {
5759                jt = r.task;
5760                if (affinity.equals(jt.affinity)) {
5761                    return j;
5762                }
5763            }
5764        }
5765
5766        // Now look forwards
5767        final int N = mMainStack.mHistory.size();
5768        jt = startTask;
5769        for (j=startIndex+1; j<N; j++) {
5770            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5771            if (r.task != jt) {
5772                if (affinity.equals(jt.affinity)) {
5773                    return j;
5774                }
5775                jt = r.task;
5776            }
5777        }
5778
5779        // Might it be at the top?
5780        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5781            return N-1;
5782        }
5783
5784        return -1;
5785    }
5786
5787    /**
5788     * TODO: Add mController hook
5789     */
5790    public void moveTaskToFront(int task, int flags, Bundle options) {
5791        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5792                "moveTaskToFront()");
5793
5794        synchronized(this) {
5795            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5796                    Binder.getCallingUid(), "Task to front")) {
5797                ActivityOptions.abort(options);
5798                return;
5799            }
5800            final long origId = Binder.clearCallingIdentity();
5801            try {
5802                TaskRecord tr = taskForIdLocked(task);
5803                if (tr != null) {
5804                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5805                        mMainStack.mUserLeaving = true;
5806                    }
5807                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5808                        // Caller wants the home activity moved with it.  To accomplish this,
5809                        // we'll just move the home task to the top first.
5810                        mMainStack.moveHomeToFrontLocked();
5811                    }
5812                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5813                    return;
5814                }
5815                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5816                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5817                    if (hr.task.taskId == task) {
5818                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5819                            mMainStack.mUserLeaving = true;
5820                        }
5821                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5822                            // Caller wants the home activity moved with it.  To accomplish this,
5823                            // we'll just move the home task to the top first.
5824                            mMainStack.moveHomeToFrontLocked();
5825                        }
5826                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5827                        return;
5828                    }
5829                }
5830            } finally {
5831                Binder.restoreCallingIdentity(origId);
5832            }
5833            ActivityOptions.abort(options);
5834        }
5835    }
5836
5837    public void moveTaskToBack(int task) {
5838        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5839                "moveTaskToBack()");
5840
5841        synchronized(this) {
5842            if (mMainStack.mResumedActivity != null
5843                    && mMainStack.mResumedActivity.task.taskId == task) {
5844                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5845                        Binder.getCallingUid(), "Task to back")) {
5846                    return;
5847                }
5848            }
5849            final long origId = Binder.clearCallingIdentity();
5850            mMainStack.moveTaskToBackLocked(task, null);
5851            Binder.restoreCallingIdentity(origId);
5852        }
5853    }
5854
5855    /**
5856     * Moves an activity, and all of the other activities within the same task, to the bottom
5857     * of the history stack.  The activity's order within the task is unchanged.
5858     *
5859     * @param token A reference to the activity we wish to move
5860     * @param nonRoot If false then this only works if the activity is the root
5861     *                of a task; if true it will work for any activity in a task.
5862     * @return Returns true if the move completed, false if not.
5863     */
5864    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5865        enforceNotIsolatedCaller("moveActivityTaskToBack");
5866        synchronized(this) {
5867            final long origId = Binder.clearCallingIdentity();
5868            int taskId = getTaskForActivityLocked(token, !nonRoot);
5869            if (taskId >= 0) {
5870                return mMainStack.moveTaskToBackLocked(taskId, null);
5871            }
5872            Binder.restoreCallingIdentity(origId);
5873        }
5874        return false;
5875    }
5876
5877    public void moveTaskBackwards(int task) {
5878        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5879                "moveTaskBackwards()");
5880
5881        synchronized(this) {
5882            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5883                    Binder.getCallingUid(), "Task backwards")) {
5884                return;
5885            }
5886            final long origId = Binder.clearCallingIdentity();
5887            moveTaskBackwardsLocked(task);
5888            Binder.restoreCallingIdentity(origId);
5889        }
5890    }
5891
5892    private final void moveTaskBackwardsLocked(int task) {
5893        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5894    }
5895
5896    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5897        synchronized(this) {
5898            return getTaskForActivityLocked(token, onlyRoot);
5899        }
5900    }
5901
5902    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5903        final int N = mMainStack.mHistory.size();
5904        TaskRecord lastTask = null;
5905        for (int i=0; i<N; i++) {
5906            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5907            if (r.appToken == token) {
5908                if (!onlyRoot || lastTask != r.task) {
5909                    return r.task.taskId;
5910                }
5911                return -1;
5912            }
5913            lastTask = r.task;
5914        }
5915
5916        return -1;
5917    }
5918
5919    // =========================================================
5920    // THUMBNAILS
5921    // =========================================================
5922
5923    public void reportThumbnail(IBinder token,
5924            Bitmap thumbnail, CharSequence description) {
5925        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5926        final long origId = Binder.clearCallingIdentity();
5927        sendPendingThumbnail(null, token, thumbnail, description, true);
5928        Binder.restoreCallingIdentity(origId);
5929    }
5930
5931    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5932            Bitmap thumbnail, CharSequence description, boolean always) {
5933        TaskRecord task = null;
5934        ArrayList receivers = null;
5935
5936        //System.out.println("Send pending thumbnail: " + r);
5937
5938        synchronized(this) {
5939            if (r == null) {
5940                r = mMainStack.isInStackLocked(token);
5941                if (r == null) {
5942                    return;
5943                }
5944            }
5945            if (thumbnail == null && r.thumbHolder != null) {
5946                thumbnail = r.thumbHolder.lastThumbnail;
5947                description = r.thumbHolder.lastDescription;
5948            }
5949            if (thumbnail == null && !always) {
5950                // If there is no thumbnail, and this entry is not actually
5951                // going away, then abort for now and pick up the next
5952                // thumbnail we get.
5953                return;
5954            }
5955            task = r.task;
5956
5957            int N = mPendingThumbnails.size();
5958            int i=0;
5959            while (i<N) {
5960                PendingThumbnailsRecord pr =
5961                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5962                //System.out.println("Looking in " + pr.pendingRecords);
5963                if (pr.pendingRecords.remove(r)) {
5964                    if (receivers == null) {
5965                        receivers = new ArrayList();
5966                    }
5967                    receivers.add(pr);
5968                    if (pr.pendingRecords.size() == 0) {
5969                        pr.finished = true;
5970                        mPendingThumbnails.remove(i);
5971                        N--;
5972                        continue;
5973                    }
5974                }
5975                i++;
5976            }
5977        }
5978
5979        if (receivers != null) {
5980            final int N = receivers.size();
5981            for (int i=0; i<N; i++) {
5982                try {
5983                    PendingThumbnailsRecord pr =
5984                        (PendingThumbnailsRecord)receivers.get(i);
5985                    pr.receiver.newThumbnail(
5986                        task != null ? task.taskId : -1, thumbnail, description);
5987                    if (pr.finished) {
5988                        pr.receiver.finished();
5989                    }
5990                } catch (Exception e) {
5991                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5992                }
5993            }
5994        }
5995    }
5996
5997    // =========================================================
5998    // CONTENT PROVIDERS
5999    // =========================================================
6000
6001    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6002        List<ProviderInfo> providers = null;
6003        try {
6004            providers = AppGlobals.getPackageManager().
6005                queryContentProviders(app.processName, app.uid,
6006                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6007        } catch (RemoteException ex) {
6008        }
6009        if (DEBUG_MU)
6010            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6011        int userId = app.userId;
6012        if (providers != null) {
6013            int N = providers.size();
6014            for (int i=0; i<N; i++) {
6015                ProviderInfo cpi =
6016                    (ProviderInfo)providers.get(i);
6017                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6018                        cpi.name, cpi.flags);
6019                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6020                    // This is a singleton provider, but a user besides the
6021                    // default user is asking to initialize a process it runs
6022                    // in...  well, no, it doesn't actually run in this process,
6023                    // it runs in the process of the default user.  Get rid of it.
6024                    providers.remove(i);
6025                    N--;
6026                    continue;
6027                }
6028
6029                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6030                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6031                if (cpr == null) {
6032                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6033                    mProviderMap.putProviderByClass(comp, cpr);
6034                }
6035                if (DEBUG_MU)
6036                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6037                app.pubProviders.put(cpi.name, cpr);
6038                app.addPackage(cpi.applicationInfo.packageName);
6039                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6040            }
6041        }
6042        return providers;
6043    }
6044
6045    /**
6046     * Check if {@link ProcessRecord} has a possible chance at accessing the
6047     * given {@link ProviderInfo}. Final permission checking is always done
6048     * in {@link ContentProvider}.
6049     */
6050    private final String checkContentProviderPermissionLocked(
6051            ProviderInfo cpi, ProcessRecord r) {
6052        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6053        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6054        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6055                cpi.applicationInfo.uid, cpi.exported)
6056                == PackageManager.PERMISSION_GRANTED) {
6057            return null;
6058        }
6059        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6060                cpi.applicationInfo.uid, cpi.exported)
6061                == PackageManager.PERMISSION_GRANTED) {
6062            return null;
6063        }
6064
6065        PathPermission[] pps = cpi.pathPermissions;
6066        if (pps != null) {
6067            int i = pps.length;
6068            while (i > 0) {
6069                i--;
6070                PathPermission pp = pps[i];
6071                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6072                        cpi.applicationInfo.uid, cpi.exported)
6073                        == PackageManager.PERMISSION_GRANTED) {
6074                    return null;
6075                }
6076                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6077                        cpi.applicationInfo.uid, cpi.exported)
6078                        == PackageManager.PERMISSION_GRANTED) {
6079                    return null;
6080                }
6081            }
6082        }
6083
6084        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6085        if (perms != null) {
6086            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6087                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6088                    return null;
6089                }
6090            }
6091        }
6092
6093        String msg;
6094        if (!cpi.exported) {
6095            msg = "Permission Denial: opening provider " + cpi.name
6096                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6097                    + ", uid=" + callingUid + ") that is not exported from uid "
6098                    + cpi.applicationInfo.uid;
6099        } else {
6100            msg = "Permission Denial: opening provider " + cpi.name
6101                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6102                    + ", uid=" + callingUid + ") requires "
6103                    + cpi.readPermission + " or " + cpi.writePermission;
6104        }
6105        Slog.w(TAG, msg);
6106        return msg;
6107    }
6108
6109    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6110            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6111        if (r != null) {
6112            for (int i=0; i<r.conProviders.size(); i++) {
6113                ContentProviderConnection conn = r.conProviders.get(i);
6114                if (conn.provider == cpr) {
6115                    if (DEBUG_PROVIDER) Slog.v(TAG,
6116                            "Adding provider requested by "
6117                            + r.processName + " from process "
6118                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6119                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6120                    if (stable) {
6121                        conn.stableCount++;
6122                        conn.numStableIncs++;
6123                    } else {
6124                        conn.unstableCount++;
6125                        conn.numUnstableIncs++;
6126                    }
6127                    return conn;
6128                }
6129            }
6130            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6131            if (stable) {
6132                conn.stableCount = 1;
6133                conn.numStableIncs = 1;
6134            } else {
6135                conn.unstableCount = 1;
6136                conn.numUnstableIncs = 1;
6137            }
6138            cpr.connections.add(conn);
6139            r.conProviders.add(conn);
6140            return conn;
6141        }
6142        cpr.addExternalProcessHandleLocked(externalProcessToken);
6143        return null;
6144    }
6145
6146    boolean decProviderCountLocked(ContentProviderConnection conn,
6147            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6148        if (conn != null) {
6149            cpr = conn.provider;
6150            if (DEBUG_PROVIDER) Slog.v(TAG,
6151                    "Removing provider requested by "
6152                    + conn.client.processName + " from process "
6153                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6154                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6155            if (stable) {
6156                conn.stableCount--;
6157            } else {
6158                conn.unstableCount--;
6159            }
6160            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6161                cpr.connections.remove(conn);
6162                conn.client.conProviders.remove(conn);
6163                return true;
6164            }
6165            return false;
6166        }
6167        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6168        return false;
6169    }
6170
6171    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6172            String name, IBinder token, boolean stable) {
6173        ContentProviderRecord cpr;
6174        ContentProviderConnection conn = null;
6175        ProviderInfo cpi = null;
6176
6177        synchronized(this) {
6178            ProcessRecord r = null;
6179            if (caller != null) {
6180                r = getRecordForAppLocked(caller);
6181                if (r == null) {
6182                    throw new SecurityException(
6183                            "Unable to find app for caller " + caller
6184                          + " (pid=" + Binder.getCallingPid()
6185                          + ") when getting content provider " + name);
6186                }
6187            }
6188
6189            // First check if this content provider has been published...
6190            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6191            cpr = mProviderMap.getProviderByName(name, userId);
6192            boolean providerRunning = cpr != null;
6193            if (providerRunning) {
6194                cpi = cpr.info;
6195                String msg;
6196                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6197                    throw new SecurityException(msg);
6198                }
6199
6200                if (r != null && cpr.canRunHere(r)) {
6201                    // This provider has been published or is in the process
6202                    // of being published...  but it is also allowed to run
6203                    // in the caller's process, so don't make a connection
6204                    // and just let the caller instantiate its own instance.
6205                    ContentProviderHolder holder = cpr.newHolder(null);
6206                    // don't give caller the provider object, it needs
6207                    // to make its own.
6208                    holder.provider = null;
6209                    return holder;
6210                }
6211
6212                final long origId = Binder.clearCallingIdentity();
6213
6214                // In this case the provider instance already exists, so we can
6215                // return it right away.
6216                conn = incProviderCountLocked(r, cpr, token, stable);
6217                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6218                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6219                        // If this is a perceptible app accessing the provider,
6220                        // make sure to count it as being accessed and thus
6221                        // back up on the LRU list.  This is good because
6222                        // content providers are often expensive to start.
6223                        updateLruProcessLocked(cpr.proc, false, true);
6224                    }
6225                }
6226
6227                if (cpr.proc != null) {
6228                    if (false) {
6229                        if (cpr.name.flattenToShortString().equals(
6230                                "com.android.providers.calendar/.CalendarProvider2")) {
6231                            Slog.v(TAG, "****************** KILLING "
6232                                + cpr.name.flattenToShortString());
6233                            Process.killProcess(cpr.proc.pid);
6234                        }
6235                    }
6236                    boolean success = updateOomAdjLocked(cpr.proc);
6237                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6238                    // NOTE: there is still a race here where a signal could be
6239                    // pending on the process even though we managed to update its
6240                    // adj level.  Not sure what to do about this, but at least
6241                    // the race is now smaller.
6242                    if (!success) {
6243                        // Uh oh...  it looks like the provider's process
6244                        // has been killed on us.  We need to wait for a new
6245                        // process to be started, and make sure its death
6246                        // doesn't kill our process.
6247                        Slog.i(TAG,
6248                                "Existing provider " + cpr.name.flattenToShortString()
6249                                + " is crashing; detaching " + r);
6250                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6251                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6252                        if (!lastRef) {
6253                            // This wasn't the last ref our process had on
6254                            // the provider...  we have now been killed, bail.
6255                            return null;
6256                        }
6257                        providerRunning = false;
6258                        conn = null;
6259                    }
6260                }
6261
6262                Binder.restoreCallingIdentity(origId);
6263            }
6264
6265            boolean singleton;
6266            if (!providerRunning) {
6267                try {
6268                    cpi = AppGlobals.getPackageManager().
6269                        resolveContentProvider(name,
6270                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6271                } catch (RemoteException ex) {
6272                }
6273                if (cpi == null) {
6274                    return null;
6275                }
6276                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6277                        cpi.name, cpi.flags);
6278                if (singleton) {
6279                    userId = 0;
6280                }
6281                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6282
6283                String msg;
6284                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6285                    throw new SecurityException(msg);
6286                }
6287
6288                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6289                        && !cpi.processName.equals("system")) {
6290                    // If this content provider does not run in the system
6291                    // process, and the system is not yet ready to run other
6292                    // processes, then fail fast instead of hanging.
6293                    throw new IllegalArgumentException(
6294                            "Attempt to launch content provider before system ready");
6295                }
6296
6297                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6298                cpr = mProviderMap.getProviderByClass(comp, userId);
6299                final boolean firstClass = cpr == null;
6300                if (firstClass) {
6301                    try {
6302                        ApplicationInfo ai =
6303                            AppGlobals.getPackageManager().
6304                                getApplicationInfo(
6305                                        cpi.applicationInfo.packageName,
6306                                        STOCK_PM_FLAGS, userId);
6307                        if (ai == null) {
6308                            Slog.w(TAG, "No package info for content provider "
6309                                    + cpi.name);
6310                            return null;
6311                        }
6312                        ai = getAppInfoForUser(ai, userId);
6313                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6314                    } catch (RemoteException ex) {
6315                        // pm is in same process, this will never happen.
6316                    }
6317                }
6318
6319                if (r != null && cpr.canRunHere(r)) {
6320                    // If this is a multiprocess provider, then just return its
6321                    // info and allow the caller to instantiate it.  Only do
6322                    // this if the provider is the same user as the caller's
6323                    // process, or can run as root (so can be in any process).
6324                    return cpr.newHolder(null);
6325                }
6326
6327                if (DEBUG_PROVIDER) {
6328                    RuntimeException e = new RuntimeException("here");
6329                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6330                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6331                }
6332
6333                // This is single process, and our app is now connecting to it.
6334                // See if we are already in the process of launching this
6335                // provider.
6336                final int N = mLaunchingProviders.size();
6337                int i;
6338                for (i=0; i<N; i++) {
6339                    if (mLaunchingProviders.get(i) == cpr) {
6340                        break;
6341                    }
6342                }
6343
6344                // If the provider is not already being launched, then get it
6345                // started.
6346                if (i >= N) {
6347                    final long origId = Binder.clearCallingIdentity();
6348
6349                    try {
6350                        // Content provider is now in use, its package can't be stopped.
6351                        try {
6352                            AppGlobals.getPackageManager().setPackageStoppedState(
6353                                    cpr.appInfo.packageName, false, userId);
6354                        } catch (RemoteException e) {
6355                        } catch (IllegalArgumentException e) {
6356                            Slog.w(TAG, "Failed trying to unstop package "
6357                                    + cpr.appInfo.packageName + ": " + e);
6358                        }
6359
6360                        ProcessRecord proc = startProcessLocked(cpi.processName,
6361                                cpr.appInfo, false, 0, "content provider",
6362                                new ComponentName(cpi.applicationInfo.packageName,
6363                                        cpi.name), false, false);
6364                        if (proc == null) {
6365                            Slog.w(TAG, "Unable to launch app "
6366                                    + cpi.applicationInfo.packageName + "/"
6367                                    + cpi.applicationInfo.uid + " for provider "
6368                                    + name + ": process is bad");
6369                            return null;
6370                        }
6371                        cpr.launchingApp = proc;
6372                        mLaunchingProviders.add(cpr);
6373                    } finally {
6374                        Binder.restoreCallingIdentity(origId);
6375                    }
6376                }
6377
6378                // Make sure the provider is published (the same provider class
6379                // may be published under multiple names).
6380                if (firstClass) {
6381                    mProviderMap.putProviderByClass(comp, cpr);
6382                }
6383
6384                mProviderMap.putProviderByName(name, cpr);
6385                conn = incProviderCountLocked(r, cpr, token, stable);
6386                if (conn != null) {
6387                    conn.waiting = true;
6388                }
6389            }
6390        }
6391
6392        // Wait for the provider to be published...
6393        synchronized (cpr) {
6394            while (cpr.provider == null) {
6395                if (cpr.launchingApp == null) {
6396                    Slog.w(TAG, "Unable to launch app "
6397                            + cpi.applicationInfo.packageName + "/"
6398                            + cpi.applicationInfo.uid + " for provider "
6399                            + name + ": launching app became null");
6400                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6401                            cpi.applicationInfo.packageName,
6402                            cpi.applicationInfo.uid, name);
6403                    return null;
6404                }
6405                try {
6406                    if (DEBUG_MU) {
6407                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6408                                + cpr.launchingApp);
6409                    }
6410                    if (conn != null) {
6411                        conn.waiting = true;
6412                    }
6413                    cpr.wait();
6414                } catch (InterruptedException ex) {
6415                } finally {
6416                    if (conn != null) {
6417                        conn.waiting = false;
6418                    }
6419                }
6420            }
6421        }
6422        return cpr != null ? cpr.newHolder(conn) : null;
6423    }
6424
6425    public final ContentProviderHolder getContentProvider(
6426            IApplicationThread caller, String name, boolean stable) {
6427        enforceNotIsolatedCaller("getContentProvider");
6428        if (caller == null) {
6429            String msg = "null IApplicationThread when getting content provider "
6430                    + name;
6431            Slog.w(TAG, msg);
6432            throw new SecurityException(msg);
6433        }
6434
6435        return getContentProviderImpl(caller, name, null, stable);
6436    }
6437
6438    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6439        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6440            "Do not have permission in call getContentProviderExternal()");
6441        return getContentProviderExternalUnchecked(name, token);
6442    }
6443
6444    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6445        return getContentProviderImpl(null, name, token, true);
6446    }
6447
6448    /**
6449     * Drop a content provider from a ProcessRecord's bookkeeping
6450     * @param cpr
6451     */
6452    public void removeContentProvider(IBinder connection, boolean stable) {
6453        enforceNotIsolatedCaller("removeContentProvider");
6454        synchronized (this) {
6455            ContentProviderConnection conn;
6456            try {
6457                conn = (ContentProviderConnection)connection;
6458            } catch (ClassCastException e) {
6459                String msg ="removeContentProvider: " + connection
6460                        + " not a ContentProviderConnection";
6461                Slog.w(TAG, msg);
6462                throw new IllegalArgumentException(msg);
6463            }
6464            if (conn == null) {
6465                throw new NullPointerException("connection is null");
6466            }
6467            if (decProviderCountLocked(conn, null, null, stable)) {
6468                updateOomAdjLocked();
6469            }
6470        }
6471    }
6472
6473    public void removeContentProviderExternal(String name, IBinder token) {
6474        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6475            "Do not have permission in call removeContentProviderExternal()");
6476        removeContentProviderExternalUnchecked(name, token);
6477    }
6478
6479    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6480        synchronized (this) {
6481            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6482                    Binder.getOrigCallingUser());
6483            if(cpr == null) {
6484                //remove from mProvidersByClass
6485                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6486                return;
6487            }
6488
6489            //update content provider record entry info
6490            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6491            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6492                    Binder.getOrigCallingUser());
6493            if (localCpr.hasExternalProcessHandles()) {
6494                if (localCpr.removeExternalProcessHandleLocked(token)) {
6495                    updateOomAdjLocked();
6496                } else {
6497                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6498                            + " with no external reference for token: "
6499                            + token + ".");
6500                }
6501            } else {
6502                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6503                        + " with no external references.");
6504            }
6505        }
6506    }
6507
6508    public final void publishContentProviders(IApplicationThread caller,
6509            List<ContentProviderHolder> providers) {
6510        if (providers == null) {
6511            return;
6512        }
6513
6514        enforceNotIsolatedCaller("publishContentProviders");
6515        synchronized (this) {
6516            final ProcessRecord r = getRecordForAppLocked(caller);
6517            if (DEBUG_MU)
6518                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6519            if (r == null) {
6520                throw new SecurityException(
6521                        "Unable to find app for caller " + caller
6522                      + " (pid=" + Binder.getCallingPid()
6523                      + ") when publishing content providers");
6524            }
6525
6526            final long origId = Binder.clearCallingIdentity();
6527
6528            final int N = providers.size();
6529            for (int i=0; i<N; i++) {
6530                ContentProviderHolder src = providers.get(i);
6531                if (src == null || src.info == null || src.provider == null) {
6532                    continue;
6533                }
6534                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6535                if (DEBUG_MU)
6536                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6537                if (dst != null) {
6538                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6539                    mProviderMap.putProviderByClass(comp, dst);
6540                    String names[] = dst.info.authority.split(";");
6541                    for (int j = 0; j < names.length; j++) {
6542                        mProviderMap.putProviderByName(names[j], dst);
6543                    }
6544
6545                    int NL = mLaunchingProviders.size();
6546                    int j;
6547                    for (j=0; j<NL; j++) {
6548                        if (mLaunchingProviders.get(j) == dst) {
6549                            mLaunchingProviders.remove(j);
6550                            j--;
6551                            NL--;
6552                        }
6553                    }
6554                    synchronized (dst) {
6555                        dst.provider = src.provider;
6556                        dst.proc = r;
6557                        dst.notifyAll();
6558                    }
6559                    updateOomAdjLocked(r);
6560                }
6561            }
6562
6563            Binder.restoreCallingIdentity(origId);
6564        }
6565    }
6566
6567    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6568        ContentProviderConnection conn;
6569        try {
6570            conn = (ContentProviderConnection)connection;
6571        } catch (ClassCastException e) {
6572            String msg ="refContentProvider: " + connection
6573                    + " not a ContentProviderConnection";
6574            Slog.w(TAG, msg);
6575            throw new IllegalArgumentException(msg);
6576        }
6577        if (conn == null) {
6578            throw new NullPointerException("connection is null");
6579        }
6580
6581        synchronized (this) {
6582            if (stable > 0) {
6583                conn.numStableIncs += stable;
6584            }
6585            stable = conn.stableCount + stable;
6586            if (stable < 0) {
6587                throw new IllegalStateException("stableCount < 0: " + stable);
6588            }
6589
6590            if (unstable > 0) {
6591                conn.numUnstableIncs += unstable;
6592            }
6593            unstable = conn.unstableCount + unstable;
6594            if (unstable < 0) {
6595                throw new IllegalStateException("unstableCount < 0: " + unstable);
6596            }
6597
6598            if ((stable+unstable) <= 0) {
6599                throw new IllegalStateException("ref counts can't go to zero here: stable="
6600                        + stable + " unstable=" + unstable);
6601            }
6602            conn.stableCount = stable;
6603            conn.unstableCount = unstable;
6604            return !conn.dead;
6605        }
6606    }
6607
6608    public void unstableProviderDied(IBinder connection) {
6609        ContentProviderConnection conn;
6610        try {
6611            conn = (ContentProviderConnection)connection;
6612        } catch (ClassCastException e) {
6613            String msg ="refContentProvider: " + connection
6614                    + " not a ContentProviderConnection";
6615            Slog.w(TAG, msg);
6616            throw new IllegalArgumentException(msg);
6617        }
6618        if (conn == null) {
6619            throw new NullPointerException("connection is null");
6620        }
6621
6622        // Safely retrieve the content provider associated with the connection.
6623        IContentProvider provider;
6624        synchronized (this) {
6625            provider = conn.provider.provider;
6626        }
6627
6628        if (provider == null) {
6629            // Um, yeah, we're way ahead of you.
6630            return;
6631        }
6632
6633        // Make sure the caller is being honest with us.
6634        if (provider.asBinder().pingBinder()) {
6635            // Er, no, still looks good to us.
6636            synchronized (this) {
6637                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6638                        + " says " + conn + " died, but we don't agree");
6639                return;
6640            }
6641        }
6642
6643        // Well look at that!  It's dead!
6644        synchronized (this) {
6645            if (conn.provider.provider != provider) {
6646                // But something changed...  good enough.
6647                return;
6648            }
6649
6650            ProcessRecord proc = conn.provider.proc;
6651            if (proc == null || proc.thread == null) {
6652                // Seems like the process is already cleaned up.
6653                return;
6654            }
6655
6656            // As far as we're concerned, this is just like receiving a
6657            // death notification...  just a bit prematurely.
6658            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6659                    + ") early provider death");
6660            final long ident = Binder.clearCallingIdentity();
6661            try {
6662                appDiedLocked(proc, proc.pid, proc.thread);
6663            } finally {
6664                Binder.restoreCallingIdentity(ident);
6665            }
6666        }
6667    }
6668
6669    public static final void installSystemProviders() {
6670        List<ProviderInfo> providers;
6671        synchronized (mSelf) {
6672            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6673            providers = mSelf.generateApplicationProvidersLocked(app);
6674            if (providers != null) {
6675                for (int i=providers.size()-1; i>=0; i--) {
6676                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6677                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6678                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6679                                + ": not system .apk");
6680                        providers.remove(i);
6681                    }
6682                }
6683            }
6684        }
6685        if (providers != null) {
6686            mSystemThread.installSystemProviders(providers);
6687        }
6688
6689        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6690
6691        mSelf.mUsageStatsService.monitorPackages();
6692    }
6693
6694    /**
6695     * Allows app to retrieve the MIME type of a URI without having permission
6696     * to access its content provider.
6697     *
6698     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6699     *
6700     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6701     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6702     */
6703    public String getProviderMimeType(Uri uri) {
6704        enforceNotIsolatedCaller("getProviderMimeType");
6705        final String name = uri.getAuthority();
6706        final long ident = Binder.clearCallingIdentity();
6707        ContentProviderHolder holder = null;
6708
6709        try {
6710            holder = getContentProviderExternalUnchecked(name, null);
6711            if (holder != null) {
6712                return holder.provider.getType(uri);
6713            }
6714        } catch (RemoteException e) {
6715            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6716            return null;
6717        } finally {
6718            if (holder != null) {
6719                removeContentProviderExternalUnchecked(name, null);
6720            }
6721            Binder.restoreCallingIdentity(ident);
6722        }
6723
6724        return null;
6725    }
6726
6727    // =========================================================
6728    // GLOBAL MANAGEMENT
6729    // =========================================================
6730
6731    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6732            ApplicationInfo info, String customProcess, boolean isolated) {
6733        String proc = customProcess != null ? customProcess : info.processName;
6734        BatteryStatsImpl.Uid.Proc ps = null;
6735        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6736        int uid = info.uid;
6737        if (isolated) {
6738            int userId = UserHandle.getUserId(uid);
6739            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6740            uid = 0;
6741            while (true) {
6742                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6743                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6744                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6745                }
6746                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6747                mNextIsolatedProcessUid++;
6748                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6749                    // No process for this uid, use it.
6750                    break;
6751                }
6752                stepsLeft--;
6753                if (stepsLeft <= 0) {
6754                    return null;
6755                }
6756            }
6757        }
6758        synchronized (stats) {
6759            ps = stats.getProcessStatsLocked(info.uid, proc);
6760        }
6761        return new ProcessRecord(ps, thread, info, proc, uid);
6762    }
6763
6764    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6765        ProcessRecord app;
6766        if (!isolated) {
6767            app = getProcessRecordLocked(info.processName, info.uid);
6768        } else {
6769            app = null;
6770        }
6771
6772        if (app == null) {
6773            app = newProcessRecordLocked(null, info, null, isolated);
6774            mProcessNames.put(info.processName, app.uid, app);
6775            if (isolated) {
6776                mIsolatedProcesses.put(app.uid, app);
6777            }
6778            updateLruProcessLocked(app, true, true);
6779        }
6780
6781        // This package really, really can not be stopped.
6782        try {
6783            AppGlobals.getPackageManager().setPackageStoppedState(
6784                    info.packageName, false, UserHandle.getUserId(app.uid));
6785        } catch (RemoteException e) {
6786        } catch (IllegalArgumentException e) {
6787            Slog.w(TAG, "Failed trying to unstop package "
6788                    + info.packageName + ": " + e);
6789        }
6790
6791        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6792                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6793            app.persistent = true;
6794            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6795        }
6796        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6797            mPersistentStartingProcesses.add(app);
6798            startProcessLocked(app, "added application", app.processName);
6799        }
6800
6801        return app;
6802    }
6803
6804    public void unhandledBack() {
6805        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6806                "unhandledBack()");
6807
6808        synchronized(this) {
6809            int count = mMainStack.mHistory.size();
6810            if (DEBUG_SWITCH) Slog.d(
6811                TAG, "Performing unhandledBack(): stack size = " + count);
6812            if (count > 1) {
6813                final long origId = Binder.clearCallingIdentity();
6814                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6815                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6816                Binder.restoreCallingIdentity(origId);
6817            }
6818        }
6819    }
6820
6821    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6822        enforceNotIsolatedCaller("openContentUri");
6823        String name = uri.getAuthority();
6824        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6825        ParcelFileDescriptor pfd = null;
6826        if (cph != null) {
6827            // We record the binder invoker's uid in thread-local storage before
6828            // going to the content provider to open the file.  Later, in the code
6829            // that handles all permissions checks, we look for this uid and use
6830            // that rather than the Activity Manager's own uid.  The effect is that
6831            // we do the check against the caller's permissions even though it looks
6832            // to the content provider like the Activity Manager itself is making
6833            // the request.
6834            sCallerIdentity.set(new Identity(
6835                    Binder.getCallingPid(), Binder.getCallingUid()));
6836            try {
6837                pfd = cph.provider.openFile(uri, "r");
6838            } catch (FileNotFoundException e) {
6839                // do nothing; pfd will be returned null
6840            } finally {
6841                // Ensure that whatever happens, we clean up the identity state
6842                sCallerIdentity.remove();
6843            }
6844
6845            // We've got the fd now, so we're done with the provider.
6846            removeContentProviderExternalUnchecked(name, null);
6847        } else {
6848            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6849        }
6850        return pfd;
6851    }
6852
6853    // Actually is sleeping or shutting down or whatever else in the future
6854    // is an inactive state.
6855    public boolean isSleeping() {
6856        return mSleeping || mShuttingDown;
6857    }
6858
6859    public void goingToSleep() {
6860        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6861                != PackageManager.PERMISSION_GRANTED) {
6862            throw new SecurityException("Requires permission "
6863                    + android.Manifest.permission.DEVICE_POWER);
6864        }
6865
6866        synchronized(this) {
6867            mWentToSleep = true;
6868            updateEventDispatchingLocked();
6869
6870            if (!mSleeping) {
6871                mSleeping = true;
6872                mMainStack.stopIfSleepingLocked();
6873
6874                // Initialize the wake times of all processes.
6875                checkExcessivePowerUsageLocked(false);
6876                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6877                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6878                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6879            }
6880        }
6881    }
6882
6883    public boolean shutdown(int timeout) {
6884        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6885                != PackageManager.PERMISSION_GRANTED) {
6886            throw new SecurityException("Requires permission "
6887                    + android.Manifest.permission.SHUTDOWN);
6888        }
6889
6890        boolean timedout = false;
6891
6892        synchronized(this) {
6893            mShuttingDown = true;
6894            updateEventDispatchingLocked();
6895
6896            if (mMainStack.mResumedActivity != null) {
6897                mMainStack.stopIfSleepingLocked();
6898                final long endTime = System.currentTimeMillis() + timeout;
6899                while (mMainStack.mResumedActivity != null
6900                        || mMainStack.mPausingActivity != null) {
6901                    long delay = endTime - System.currentTimeMillis();
6902                    if (delay <= 0) {
6903                        Slog.w(TAG, "Activity manager shutdown timed out");
6904                        timedout = true;
6905                        break;
6906                    }
6907                    try {
6908                        this.wait();
6909                    } catch (InterruptedException e) {
6910                    }
6911                }
6912            }
6913        }
6914
6915        mUsageStatsService.shutdown();
6916        mBatteryStatsService.shutdown();
6917
6918        return timedout;
6919    }
6920
6921    public final void activitySlept(IBinder token) {
6922        if (localLOGV) Slog.v(
6923            TAG, "Activity slept: token=" + token);
6924
6925        ActivityRecord r = null;
6926
6927        final long origId = Binder.clearCallingIdentity();
6928
6929        synchronized (this) {
6930            r = mMainStack.isInStackLocked(token);
6931            if (r != null) {
6932                mMainStack.activitySleptLocked(r);
6933            }
6934        }
6935
6936        Binder.restoreCallingIdentity(origId);
6937    }
6938
6939    private void comeOutOfSleepIfNeededLocked() {
6940        if (!mWentToSleep && !mLockScreenShown) {
6941            if (mSleeping) {
6942                mSleeping = false;
6943                mMainStack.awakeFromSleepingLocked();
6944                mMainStack.resumeTopActivityLocked(null);
6945            }
6946        }
6947    }
6948
6949    public void wakingUp() {
6950        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6951                != PackageManager.PERMISSION_GRANTED) {
6952            throw new SecurityException("Requires permission "
6953                    + android.Manifest.permission.DEVICE_POWER);
6954        }
6955
6956        synchronized(this) {
6957            mWentToSleep = false;
6958            updateEventDispatchingLocked();
6959            comeOutOfSleepIfNeededLocked();
6960        }
6961    }
6962
6963    private void updateEventDispatchingLocked() {
6964        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6965    }
6966
6967    public void setLockScreenShown(boolean shown) {
6968        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6969                != PackageManager.PERMISSION_GRANTED) {
6970            throw new SecurityException("Requires permission "
6971                    + android.Manifest.permission.DEVICE_POWER);
6972        }
6973
6974        synchronized(this) {
6975            mLockScreenShown = shown;
6976            comeOutOfSleepIfNeededLocked();
6977        }
6978    }
6979
6980    public void stopAppSwitches() {
6981        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6982                != PackageManager.PERMISSION_GRANTED) {
6983            throw new SecurityException("Requires permission "
6984                    + android.Manifest.permission.STOP_APP_SWITCHES);
6985        }
6986
6987        synchronized(this) {
6988            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6989                    + APP_SWITCH_DELAY_TIME;
6990            mDidAppSwitch = false;
6991            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6992            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6993            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6994        }
6995    }
6996
6997    public void resumeAppSwitches() {
6998        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6999                != PackageManager.PERMISSION_GRANTED) {
7000            throw new SecurityException("Requires permission "
7001                    + android.Manifest.permission.STOP_APP_SWITCHES);
7002        }
7003
7004        synchronized(this) {
7005            // Note that we don't execute any pending app switches... we will
7006            // let those wait until either the timeout, or the next start
7007            // activity request.
7008            mAppSwitchesAllowedTime = 0;
7009        }
7010    }
7011
7012    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7013            String name) {
7014        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7015            return true;
7016        }
7017
7018        final int perm = checkComponentPermission(
7019                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7020                callingUid, -1, true);
7021        if (perm == PackageManager.PERMISSION_GRANTED) {
7022            return true;
7023        }
7024
7025        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7026        return false;
7027    }
7028
7029    public void setDebugApp(String packageName, boolean waitForDebugger,
7030            boolean persistent) {
7031        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7032                "setDebugApp()");
7033
7034        // Note that this is not really thread safe if there are multiple
7035        // callers into it at the same time, but that's not a situation we
7036        // care about.
7037        if (persistent) {
7038            final ContentResolver resolver = mContext.getContentResolver();
7039            Settings.System.putString(
7040                resolver, Settings.System.DEBUG_APP,
7041                packageName);
7042            Settings.System.putInt(
7043                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7044                waitForDebugger ? 1 : 0);
7045        }
7046
7047        synchronized (this) {
7048            if (!persistent) {
7049                mOrigDebugApp = mDebugApp;
7050                mOrigWaitForDebugger = mWaitForDebugger;
7051            }
7052            mDebugApp = packageName;
7053            mWaitForDebugger = waitForDebugger;
7054            mDebugTransient = !persistent;
7055            if (packageName != null) {
7056                final long origId = Binder.clearCallingIdentity();
7057                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7058                Binder.restoreCallingIdentity(origId);
7059            }
7060        }
7061    }
7062
7063    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7064        synchronized (this) {
7065            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7066            if (!isDebuggable) {
7067                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7068                    throw new SecurityException("Process not debuggable: " + app.packageName);
7069                }
7070            }
7071
7072            mOpenGlTraceApp = processName;
7073        }
7074    }
7075
7076    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7077            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7078        synchronized (this) {
7079            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7080            if (!isDebuggable) {
7081                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7082                    throw new SecurityException("Process not debuggable: " + app.packageName);
7083                }
7084            }
7085            mProfileApp = processName;
7086            mProfileFile = profileFile;
7087            if (mProfileFd != null) {
7088                try {
7089                    mProfileFd.close();
7090                } catch (IOException e) {
7091                }
7092                mProfileFd = null;
7093            }
7094            mProfileFd = profileFd;
7095            mProfileType = 0;
7096            mAutoStopProfiler = autoStopProfiler;
7097        }
7098    }
7099
7100    public void setAlwaysFinish(boolean enabled) {
7101        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7102                "setAlwaysFinish()");
7103
7104        Settings.System.putInt(
7105                mContext.getContentResolver(),
7106                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7107
7108        synchronized (this) {
7109            mAlwaysFinishActivities = enabled;
7110        }
7111    }
7112
7113    public void setActivityController(IActivityController controller) {
7114        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7115                "setActivityController()");
7116        synchronized (this) {
7117            mController = controller;
7118        }
7119    }
7120
7121    public boolean isUserAMonkey() {
7122        // For now the fact that there is a controller implies
7123        // we have a monkey.
7124        synchronized (this) {
7125            return mController != null;
7126        }
7127    }
7128
7129    public void registerProcessObserver(IProcessObserver observer) {
7130        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7131                "registerProcessObserver()");
7132        synchronized (this) {
7133            mProcessObservers.register(observer);
7134        }
7135    }
7136
7137    public void unregisterProcessObserver(IProcessObserver observer) {
7138        synchronized (this) {
7139            mProcessObservers.unregister(observer);
7140        }
7141    }
7142
7143    public void setImmersive(IBinder token, boolean immersive) {
7144        synchronized(this) {
7145            ActivityRecord r = mMainStack.isInStackLocked(token);
7146            if (r == null) {
7147                throw new IllegalArgumentException();
7148            }
7149            r.immersive = immersive;
7150        }
7151    }
7152
7153    public boolean isImmersive(IBinder token) {
7154        synchronized (this) {
7155            ActivityRecord r = mMainStack.isInStackLocked(token);
7156            if (r == null) {
7157                throw new IllegalArgumentException();
7158            }
7159            return r.immersive;
7160        }
7161    }
7162
7163    public boolean isTopActivityImmersive() {
7164        enforceNotIsolatedCaller("startActivity");
7165        synchronized (this) {
7166            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7167            return (r != null) ? r.immersive : false;
7168        }
7169    }
7170
7171    public final void enterSafeMode() {
7172        synchronized(this) {
7173            // It only makes sense to do this before the system is ready
7174            // and started launching other packages.
7175            if (!mSystemReady) {
7176                try {
7177                    AppGlobals.getPackageManager().enterSafeMode();
7178                } catch (RemoteException e) {
7179                }
7180            }
7181        }
7182    }
7183
7184    public final void showSafeModeOverlay() {
7185        View v = LayoutInflater.from(mContext).inflate(
7186                com.android.internal.R.layout.safe_mode, null);
7187        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7188        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7189        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7190        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7191        lp.gravity = Gravity.BOTTOM | Gravity.START;
7192        lp.format = v.getBackground().getOpacity();
7193        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7194                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7195        ((WindowManager)mContext.getSystemService(
7196                Context.WINDOW_SERVICE)).addView(v, lp);
7197    }
7198
7199    public void noteWakeupAlarm(IIntentSender sender) {
7200        if (!(sender instanceof PendingIntentRecord)) {
7201            return;
7202        }
7203        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7204        synchronized (stats) {
7205            if (mBatteryStatsService.isOnBattery()) {
7206                mBatteryStatsService.enforceCallingPermission();
7207                PendingIntentRecord rec = (PendingIntentRecord)sender;
7208                int MY_UID = Binder.getCallingUid();
7209                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7210                BatteryStatsImpl.Uid.Pkg pkg =
7211                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7212                pkg.incWakeupsLocked();
7213            }
7214        }
7215    }
7216
7217    public boolean killPids(int[] pids, String pReason, boolean secure) {
7218        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7219            throw new SecurityException("killPids only available to the system");
7220        }
7221        String reason = (pReason == null) ? "Unknown" : pReason;
7222        // XXX Note: don't acquire main activity lock here, because the window
7223        // manager calls in with its locks held.
7224
7225        boolean killed = false;
7226        synchronized (mPidsSelfLocked) {
7227            int[] types = new int[pids.length];
7228            int worstType = 0;
7229            for (int i=0; i<pids.length; i++) {
7230                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7231                if (proc != null) {
7232                    int type = proc.setAdj;
7233                    types[i] = type;
7234                    if (type > worstType) {
7235                        worstType = type;
7236                    }
7237                }
7238            }
7239
7240            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7241            // then constrain it so we will kill all hidden procs.
7242            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7243                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7244                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7245            }
7246
7247            // If this is not a secure call, don't let it kill processes that
7248            // are important.
7249            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7250                worstType = ProcessList.SERVICE_ADJ;
7251            }
7252
7253            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7254            for (int i=0; i<pids.length; i++) {
7255                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7256                if (proc == null) {
7257                    continue;
7258                }
7259                int adj = proc.setAdj;
7260                if (adj >= worstType && !proc.killedBackground) {
7261                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7262                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7263                            proc.processName, adj, reason);
7264                    killed = true;
7265                    proc.killedBackground = true;
7266                    Process.killProcessQuiet(pids[i]);
7267                }
7268            }
7269        }
7270        return killed;
7271    }
7272
7273    @Override
7274    public boolean killProcessesBelowForeground(String reason) {
7275        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7276            throw new SecurityException("killProcessesBelowForeground() only available to system");
7277        }
7278
7279        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7280    }
7281
7282    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7283        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7284            throw new SecurityException("killProcessesBelowAdj() only available to system");
7285        }
7286
7287        boolean killed = false;
7288        synchronized (mPidsSelfLocked) {
7289            final int size = mPidsSelfLocked.size();
7290            for (int i = 0; i < size; i++) {
7291                final int pid = mPidsSelfLocked.keyAt(i);
7292                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7293                if (proc == null) continue;
7294
7295                final int adj = proc.setAdj;
7296                if (adj > belowAdj && !proc.killedBackground) {
7297                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7298                    EventLog.writeEvent(
7299                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7300                    killed = true;
7301                    proc.killedBackground = true;
7302                    Process.killProcessQuiet(pid);
7303                }
7304            }
7305        }
7306        return killed;
7307    }
7308
7309    public final void startRunning(String pkg, String cls, String action,
7310            String data) {
7311        synchronized(this) {
7312            if (mStartRunning) {
7313                return;
7314            }
7315            mStartRunning = true;
7316            mTopComponent = pkg != null && cls != null
7317                    ? new ComponentName(pkg, cls) : null;
7318            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7319            mTopData = data;
7320            if (!mSystemReady) {
7321                return;
7322            }
7323        }
7324
7325        systemReady(null);
7326    }
7327
7328    private void retrieveSettings() {
7329        final ContentResolver resolver = mContext.getContentResolver();
7330        String debugApp = Settings.System.getString(
7331            resolver, Settings.System.DEBUG_APP);
7332        boolean waitForDebugger = Settings.System.getInt(
7333            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7334        boolean alwaysFinishActivities = Settings.System.getInt(
7335            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7336
7337        Configuration configuration = new Configuration();
7338        Settings.System.getConfiguration(resolver, configuration);
7339
7340        synchronized (this) {
7341            mDebugApp = mOrigDebugApp = debugApp;
7342            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7343            mAlwaysFinishActivities = alwaysFinishActivities;
7344            // This happens before any activities are started, so we can
7345            // change mConfiguration in-place.
7346            updateConfigurationLocked(configuration, null, false, true);
7347            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7348        }
7349    }
7350
7351    public boolean testIsSystemReady() {
7352        // no need to synchronize(this) just to read & return the value
7353        return mSystemReady;
7354    }
7355
7356    private static File getCalledPreBootReceiversFile() {
7357        File dataDir = Environment.getDataDirectory();
7358        File systemDir = new File(dataDir, "system");
7359        File fname = new File(systemDir, "called_pre_boots.dat");
7360        return fname;
7361    }
7362
7363    static final int LAST_DONE_VERSION = 10000;
7364
7365    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7366        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7367        File file = getCalledPreBootReceiversFile();
7368        FileInputStream fis = null;
7369        try {
7370            fis = new FileInputStream(file);
7371            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7372            int fvers = dis.readInt();
7373            if (fvers == LAST_DONE_VERSION) {
7374                String vers = dis.readUTF();
7375                String codename = dis.readUTF();
7376                String build = dis.readUTF();
7377                if (android.os.Build.VERSION.RELEASE.equals(vers)
7378                        && android.os.Build.VERSION.CODENAME.equals(codename)
7379                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7380                    int num = dis.readInt();
7381                    while (num > 0) {
7382                        num--;
7383                        String pkg = dis.readUTF();
7384                        String cls = dis.readUTF();
7385                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7386                    }
7387                }
7388            }
7389        } catch (FileNotFoundException e) {
7390        } catch (IOException e) {
7391            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7392        } finally {
7393            if (fis != null) {
7394                try {
7395                    fis.close();
7396                } catch (IOException e) {
7397                }
7398            }
7399        }
7400        return lastDoneReceivers;
7401    }
7402
7403    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7404        File file = getCalledPreBootReceiversFile();
7405        FileOutputStream fos = null;
7406        DataOutputStream dos = null;
7407        try {
7408            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7409            fos = new FileOutputStream(file);
7410            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7411            dos.writeInt(LAST_DONE_VERSION);
7412            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7413            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7414            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7415            dos.writeInt(list.size());
7416            for (int i=0; i<list.size(); i++) {
7417                dos.writeUTF(list.get(i).getPackageName());
7418                dos.writeUTF(list.get(i).getClassName());
7419            }
7420        } catch (IOException e) {
7421            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7422            file.delete();
7423        } finally {
7424            FileUtils.sync(fos);
7425            if (dos != null) {
7426                try {
7427                    dos.close();
7428                } catch (IOException e) {
7429                    // TODO Auto-generated catch block
7430                    e.printStackTrace();
7431                }
7432            }
7433        }
7434    }
7435
7436    public void systemReady(final Runnable goingCallback) {
7437        synchronized(this) {
7438            if (mSystemReady) {
7439                if (goingCallback != null) goingCallback.run();
7440                return;
7441            }
7442
7443            // Check to see if there are any update receivers to run.
7444            if (!mDidUpdate) {
7445                if (mWaitingUpdate) {
7446                    return;
7447                }
7448                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7449                List<ResolveInfo> ris = null;
7450                try {
7451                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7452                            intent, null, 0, 0);
7453                } catch (RemoteException e) {
7454                }
7455                if (ris != null) {
7456                    for (int i=ris.size()-1; i>=0; i--) {
7457                        if ((ris.get(i).activityInfo.applicationInfo.flags
7458                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7459                            ris.remove(i);
7460                        }
7461                    }
7462                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7463
7464                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7465
7466                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7467                    for (int i=0; i<ris.size(); i++) {
7468                        ActivityInfo ai = ris.get(i).activityInfo;
7469                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7470                        if (lastDoneReceivers.contains(comp)) {
7471                            ris.remove(i);
7472                            i--;
7473                        }
7474                    }
7475
7476                    for (int i=0; i<ris.size(); i++) {
7477                        ActivityInfo ai = ris.get(i).activityInfo;
7478                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7479                        doneReceivers.add(comp);
7480                        intent.setComponent(comp);
7481                        IIntentReceiver finisher = null;
7482                        if (i == ris.size()-1) {
7483                            finisher = new IIntentReceiver.Stub() {
7484                                public void performReceive(Intent intent, int resultCode,
7485                                        String data, Bundle extras, boolean ordered,
7486                                        boolean sticky) {
7487                                    // The raw IIntentReceiver interface is called
7488                                    // with the AM lock held, so redispatch to
7489                                    // execute our code without the lock.
7490                                    mHandler.post(new Runnable() {
7491                                        public void run() {
7492                                            synchronized (ActivityManagerService.this) {
7493                                                mDidUpdate = true;
7494                                            }
7495                                            writeLastDonePreBootReceivers(doneReceivers);
7496                                            showBootMessage(mContext.getText(
7497                                                    R.string.android_upgrading_complete),
7498                                                    false);
7499                                            systemReady(goingCallback);
7500                                        }
7501                                    });
7502                                }
7503                            };
7504                        }
7505                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7506                        /* TODO: Send this to all users */
7507                        broadcastIntentLocked(null, null, intent, null, finisher,
7508                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7509                                0 /* UserId zero */);
7510                        if (finisher != null) {
7511                            mWaitingUpdate = true;
7512                        }
7513                    }
7514                }
7515                if (mWaitingUpdate) {
7516                    return;
7517                }
7518                mDidUpdate = true;
7519            }
7520
7521            mSystemReady = true;
7522            if (!mStartRunning) {
7523                return;
7524            }
7525        }
7526
7527        ArrayList<ProcessRecord> procsToKill = null;
7528        synchronized(mPidsSelfLocked) {
7529            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7530                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7531                if (!isAllowedWhileBooting(proc.info)){
7532                    if (procsToKill == null) {
7533                        procsToKill = new ArrayList<ProcessRecord>();
7534                    }
7535                    procsToKill.add(proc);
7536                }
7537            }
7538        }
7539
7540        synchronized(this) {
7541            if (procsToKill != null) {
7542                for (int i=procsToKill.size()-1; i>=0; i--) {
7543                    ProcessRecord proc = procsToKill.get(i);
7544                    Slog.i(TAG, "Removing system update proc: " + proc);
7545                    removeProcessLocked(proc, true, false, "system update done");
7546                }
7547            }
7548
7549            // Now that we have cleaned up any update processes, we
7550            // are ready to start launching real processes and know that
7551            // we won't trample on them any more.
7552            mProcessesReady = true;
7553        }
7554
7555        Slog.i(TAG, "System now ready");
7556        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7557            SystemClock.uptimeMillis());
7558
7559        synchronized(this) {
7560            // Make sure we have no pre-ready processes sitting around.
7561
7562            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7563                ResolveInfo ri = mContext.getPackageManager()
7564                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7565                                STOCK_PM_FLAGS);
7566                CharSequence errorMsg = null;
7567                if (ri != null) {
7568                    ActivityInfo ai = ri.activityInfo;
7569                    ApplicationInfo app = ai.applicationInfo;
7570                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7571                        mTopAction = Intent.ACTION_FACTORY_TEST;
7572                        mTopData = null;
7573                        mTopComponent = new ComponentName(app.packageName,
7574                                ai.name);
7575                    } else {
7576                        errorMsg = mContext.getResources().getText(
7577                                com.android.internal.R.string.factorytest_not_system);
7578                    }
7579                } else {
7580                    errorMsg = mContext.getResources().getText(
7581                            com.android.internal.R.string.factorytest_no_action);
7582                }
7583                if (errorMsg != null) {
7584                    mTopAction = null;
7585                    mTopData = null;
7586                    mTopComponent = null;
7587                    Message msg = Message.obtain();
7588                    msg.what = SHOW_FACTORY_ERROR_MSG;
7589                    msg.getData().putCharSequence("msg", errorMsg);
7590                    mHandler.sendMessage(msg);
7591                }
7592            }
7593        }
7594
7595        retrieveSettings();
7596
7597        if (goingCallback != null) goingCallback.run();
7598
7599        synchronized (this) {
7600            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7601                try {
7602                    List apps = AppGlobals.getPackageManager().
7603                        getPersistentApplications(STOCK_PM_FLAGS);
7604                    if (apps != null) {
7605                        int N = apps.size();
7606                        int i;
7607                        for (i=0; i<N; i++) {
7608                            ApplicationInfo info
7609                                = (ApplicationInfo)apps.get(i);
7610                            if (info != null &&
7611                                    !info.packageName.equals("android")) {
7612                                addAppLocked(info, false);
7613                            }
7614                        }
7615                    }
7616                } catch (RemoteException ex) {
7617                    // pm is in same process, this will never happen.
7618                }
7619            }
7620
7621            // Start up initial activity.
7622            mBooting = true;
7623
7624            try {
7625                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7626                    Message msg = Message.obtain();
7627                    msg.what = SHOW_UID_ERROR_MSG;
7628                    mHandler.sendMessage(msg);
7629                }
7630            } catch (RemoteException e) {
7631            }
7632
7633            mMainStack.resumeTopActivityLocked(null);
7634        }
7635    }
7636
7637    private boolean makeAppCrashingLocked(ProcessRecord app,
7638            String shortMsg, String longMsg, String stackTrace) {
7639        app.crashing = true;
7640        app.crashingReport = generateProcessError(app,
7641                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7642        startAppProblemLocked(app);
7643        app.stopFreezingAllLocked();
7644        return handleAppCrashLocked(app);
7645    }
7646
7647    private void makeAppNotRespondingLocked(ProcessRecord app,
7648            String activity, String shortMsg, String longMsg) {
7649        app.notResponding = true;
7650        app.notRespondingReport = generateProcessError(app,
7651                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7652                activity, shortMsg, longMsg, null);
7653        startAppProblemLocked(app);
7654        app.stopFreezingAllLocked();
7655    }
7656
7657    /**
7658     * Generate a process error record, suitable for attachment to a ProcessRecord.
7659     *
7660     * @param app The ProcessRecord in which the error occurred.
7661     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7662     *                      ActivityManager.AppErrorStateInfo
7663     * @param activity The activity associated with the crash, if known.
7664     * @param shortMsg Short message describing the crash.
7665     * @param longMsg Long message describing the crash.
7666     * @param stackTrace Full crash stack trace, may be null.
7667     *
7668     * @return Returns a fully-formed AppErrorStateInfo record.
7669     */
7670    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7671            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7672        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7673
7674        report.condition = condition;
7675        report.processName = app.processName;
7676        report.pid = app.pid;
7677        report.uid = app.info.uid;
7678        report.tag = activity;
7679        report.shortMsg = shortMsg;
7680        report.longMsg = longMsg;
7681        report.stackTrace = stackTrace;
7682
7683        return report;
7684    }
7685
7686    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7687        synchronized (this) {
7688            app.crashing = false;
7689            app.crashingReport = null;
7690            app.notResponding = false;
7691            app.notRespondingReport = null;
7692            if (app.anrDialog == fromDialog) {
7693                app.anrDialog = null;
7694            }
7695            if (app.waitDialog == fromDialog) {
7696                app.waitDialog = null;
7697            }
7698            if (app.pid > 0 && app.pid != MY_PID) {
7699                handleAppCrashLocked(app);
7700                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7701                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7702                        app.processName, app.setAdj, "user's request after error");
7703                Process.killProcessQuiet(app.pid);
7704            }
7705        }
7706    }
7707
7708    private boolean handleAppCrashLocked(ProcessRecord app) {
7709        if (mHeadless) {
7710            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7711            return false;
7712        }
7713        long now = SystemClock.uptimeMillis();
7714
7715        Long crashTime;
7716        if (!app.isolated) {
7717            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7718        } else {
7719            crashTime = null;
7720        }
7721        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7722            // This process loses!
7723            Slog.w(TAG, "Process " + app.info.processName
7724                    + " has crashed too many times: killing!");
7725            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7726                    app.info.processName, app.uid);
7727            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7728                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7729                if (r.app == app) {
7730                    Slog.w(TAG, "  Force finishing activity "
7731                        + r.intent.getComponent().flattenToShortString());
7732                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7733                }
7734            }
7735            if (!app.persistent) {
7736                // We don't want to start this process again until the user
7737                // explicitly does so...  but for persistent process, we really
7738                // need to keep it running.  If a persistent process is actually
7739                // repeatedly crashing, then badness for everyone.
7740                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7741                        app.info.processName);
7742                if (!app.isolated) {
7743                    // XXX We don't have a way to mark isolated processes
7744                    // as bad, since they don't have a peristent identity.
7745                    mBadProcesses.put(app.info.processName, app.uid, now);
7746                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7747                }
7748                app.bad = true;
7749                app.removed = true;
7750                // Don't let services in this process be restarted and potentially
7751                // annoy the user repeatedly.  Unless it is persistent, since those
7752                // processes run critical code.
7753                removeProcessLocked(app, false, false, "crash");
7754                mMainStack.resumeTopActivityLocked(null);
7755                return false;
7756            }
7757            mMainStack.resumeTopActivityLocked(null);
7758        } else {
7759            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7760            if (r != null && r.app == app) {
7761                // If the top running activity is from this crashing
7762                // process, then terminate it to avoid getting in a loop.
7763                Slog.w(TAG, "  Force finishing activity "
7764                        + r.intent.getComponent().flattenToShortString());
7765                int index = mMainStack.indexOfActivityLocked(r);
7766                r.stack.finishActivityLocked(r, index,
7767                        Activity.RESULT_CANCELED, null, "crashed");
7768                // Also terminate any activities below it that aren't yet
7769                // stopped, to avoid a situation where one will get
7770                // re-start our crashing activity once it gets resumed again.
7771                index--;
7772                if (index >= 0) {
7773                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7774                    if (r.state == ActivityState.RESUMED
7775                            || r.state == ActivityState.PAUSING
7776                            || r.state == ActivityState.PAUSED) {
7777                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7778                            Slog.w(TAG, "  Force finishing activity "
7779                                    + r.intent.getComponent().flattenToShortString());
7780                            r.stack.finishActivityLocked(r, index,
7781                                    Activity.RESULT_CANCELED, null, "crashed");
7782                        }
7783                    }
7784                }
7785            }
7786        }
7787
7788        // Bump up the crash count of any services currently running in the proc.
7789        if (app.services.size() != 0) {
7790            // Any services running in the application need to be placed
7791            // back in the pending list.
7792            Iterator<ServiceRecord> it = app.services.iterator();
7793            while (it.hasNext()) {
7794                ServiceRecord sr = it.next();
7795                sr.crashCount++;
7796            }
7797        }
7798
7799        // If the crashing process is what we consider to be the "home process" and it has been
7800        // replaced by a third-party app, clear the package preferred activities from packages
7801        // with a home activity running in the process to prevent a repeatedly crashing app
7802        // from blocking the user to manually clear the list.
7803        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7804                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7805            Iterator it = mHomeProcess.activities.iterator();
7806            while (it.hasNext()) {
7807                ActivityRecord r = (ActivityRecord)it.next();
7808                if (r.isHomeActivity) {
7809                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7810                    try {
7811                        ActivityThread.getPackageManager()
7812                                .clearPackagePreferredActivities(r.packageName);
7813                    } catch (RemoteException c) {
7814                        // pm is in same process, this will never happen.
7815                    }
7816                }
7817            }
7818        }
7819
7820        if (!app.isolated) {
7821            // XXX Can't keep track of crash times for isolated processes,
7822            // because they don't have a perisistent identity.
7823            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7824        }
7825
7826        return true;
7827    }
7828
7829    void startAppProblemLocked(ProcessRecord app) {
7830        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7831                mContext, app.info.packageName, app.info.flags);
7832        skipCurrentReceiverLocked(app);
7833    }
7834
7835    void skipCurrentReceiverLocked(ProcessRecord app) {
7836        for (BroadcastQueue queue : mBroadcastQueues) {
7837            queue.skipCurrentReceiverLocked(app);
7838        }
7839    }
7840
7841    /**
7842     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7843     * The application process will exit immediately after this call returns.
7844     * @param app object of the crashing app, null for the system server
7845     * @param crashInfo describing the exception
7846     */
7847    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7848        ProcessRecord r = findAppProcess(app, "Crash");
7849        final String processName = app == null ? "system_server"
7850                : (r == null ? "unknown" : r.processName);
7851
7852        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7853                processName,
7854                r == null ? -1 : r.info.flags,
7855                crashInfo.exceptionClassName,
7856                crashInfo.exceptionMessage,
7857                crashInfo.throwFileName,
7858                crashInfo.throwLineNumber);
7859
7860        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7861
7862        crashApplication(r, crashInfo);
7863    }
7864
7865    public void handleApplicationStrictModeViolation(
7866            IBinder app,
7867            int violationMask,
7868            StrictMode.ViolationInfo info) {
7869        ProcessRecord r = findAppProcess(app, "StrictMode");
7870        if (r == null) {
7871            return;
7872        }
7873
7874        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7875            Integer stackFingerprint = info.hashCode();
7876            boolean logIt = true;
7877            synchronized (mAlreadyLoggedViolatedStacks) {
7878                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7879                    logIt = false;
7880                    // TODO: sub-sample into EventLog for these, with
7881                    // the info.durationMillis?  Then we'd get
7882                    // the relative pain numbers, without logging all
7883                    // the stack traces repeatedly.  We'd want to do
7884                    // likewise in the client code, which also does
7885                    // dup suppression, before the Binder call.
7886                } else {
7887                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7888                        mAlreadyLoggedViolatedStacks.clear();
7889                    }
7890                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7891                }
7892            }
7893            if (logIt) {
7894                logStrictModeViolationToDropBox(r, info);
7895            }
7896        }
7897
7898        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7899            AppErrorResult result = new AppErrorResult();
7900            synchronized (this) {
7901                final long origId = Binder.clearCallingIdentity();
7902
7903                Message msg = Message.obtain();
7904                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7905                HashMap<String, Object> data = new HashMap<String, Object>();
7906                data.put("result", result);
7907                data.put("app", r);
7908                data.put("violationMask", violationMask);
7909                data.put("info", info);
7910                msg.obj = data;
7911                mHandler.sendMessage(msg);
7912
7913                Binder.restoreCallingIdentity(origId);
7914            }
7915            int res = result.get();
7916            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7917        }
7918    }
7919
7920    // Depending on the policy in effect, there could be a bunch of
7921    // these in quick succession so we try to batch these together to
7922    // minimize disk writes, number of dropbox entries, and maximize
7923    // compression, by having more fewer, larger records.
7924    private void logStrictModeViolationToDropBox(
7925            ProcessRecord process,
7926            StrictMode.ViolationInfo info) {
7927        if (info == null) {
7928            return;
7929        }
7930        final boolean isSystemApp = process == null ||
7931                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7932                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7933        final String processName = process == null ? "unknown" : process.processName;
7934        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7935        final DropBoxManager dbox = (DropBoxManager)
7936                mContext.getSystemService(Context.DROPBOX_SERVICE);
7937
7938        // Exit early if the dropbox isn't configured to accept this report type.
7939        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7940
7941        boolean bufferWasEmpty;
7942        boolean needsFlush;
7943        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7944        synchronized (sb) {
7945            bufferWasEmpty = sb.length() == 0;
7946            appendDropBoxProcessHeaders(process, processName, sb);
7947            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7948            sb.append("System-App: ").append(isSystemApp).append("\n");
7949            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7950            if (info.violationNumThisLoop != 0) {
7951                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7952            }
7953            if (info.numAnimationsRunning != 0) {
7954                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7955            }
7956            if (info.broadcastIntentAction != null) {
7957                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7958            }
7959            if (info.durationMillis != -1) {
7960                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7961            }
7962            if (info.numInstances != -1) {
7963                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7964            }
7965            if (info.tags != null) {
7966                for (String tag : info.tags) {
7967                    sb.append("Span-Tag: ").append(tag).append("\n");
7968                }
7969            }
7970            sb.append("\n");
7971            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7972                sb.append(info.crashInfo.stackTrace);
7973            }
7974            sb.append("\n");
7975
7976            // Only buffer up to ~64k.  Various logging bits truncate
7977            // things at 128k.
7978            needsFlush = (sb.length() > 64 * 1024);
7979        }
7980
7981        // Flush immediately if the buffer's grown too large, or this
7982        // is a non-system app.  Non-system apps are isolated with a
7983        // different tag & policy and not batched.
7984        //
7985        // Batching is useful during internal testing with
7986        // StrictMode settings turned up high.  Without batching,
7987        // thousands of separate files could be created on boot.
7988        if (!isSystemApp || needsFlush) {
7989            new Thread("Error dump: " + dropboxTag) {
7990                @Override
7991                public void run() {
7992                    String report;
7993                    synchronized (sb) {
7994                        report = sb.toString();
7995                        sb.delete(0, sb.length());
7996                        sb.trimToSize();
7997                    }
7998                    if (report.length() != 0) {
7999                        dbox.addText(dropboxTag, report);
8000                    }
8001                }
8002            }.start();
8003            return;
8004        }
8005
8006        // System app batching:
8007        if (!bufferWasEmpty) {
8008            // An existing dropbox-writing thread is outstanding, so
8009            // we don't need to start it up.  The existing thread will
8010            // catch the buffer appends we just did.
8011            return;
8012        }
8013
8014        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8015        // (After this point, we shouldn't access AMS internal data structures.)
8016        new Thread("Error dump: " + dropboxTag) {
8017            @Override
8018            public void run() {
8019                // 5 second sleep to let stacks arrive and be batched together
8020                try {
8021                    Thread.sleep(5000);  // 5 seconds
8022                } catch (InterruptedException e) {}
8023
8024                String errorReport;
8025                synchronized (mStrictModeBuffer) {
8026                    errorReport = mStrictModeBuffer.toString();
8027                    if (errorReport.length() == 0) {
8028                        return;
8029                    }
8030                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8031                    mStrictModeBuffer.trimToSize();
8032                }
8033                dbox.addText(dropboxTag, errorReport);
8034            }
8035        }.start();
8036    }
8037
8038    /**
8039     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8040     * @param app object of the crashing app, null for the system server
8041     * @param tag reported by the caller
8042     * @param crashInfo describing the context of the error
8043     * @return true if the process should exit immediately (WTF is fatal)
8044     */
8045    public boolean handleApplicationWtf(IBinder app, String tag,
8046            ApplicationErrorReport.CrashInfo crashInfo) {
8047        ProcessRecord r = findAppProcess(app, "WTF");
8048        final String processName = app == null ? "system_server"
8049                : (r == null ? "unknown" : r.processName);
8050
8051        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8052                processName,
8053                r == null ? -1 : r.info.flags,
8054                tag, crashInfo.exceptionMessage);
8055
8056        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8057
8058        if (r != null && r.pid != Process.myPid() &&
8059                Settings.Secure.getInt(mContext.getContentResolver(),
8060                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8061            crashApplication(r, crashInfo);
8062            return true;
8063        } else {
8064            return false;
8065        }
8066    }
8067
8068    /**
8069     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8070     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8071     */
8072    private ProcessRecord findAppProcess(IBinder app, String reason) {
8073        if (app == null) {
8074            return null;
8075        }
8076
8077        synchronized (this) {
8078            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8079                final int NA = apps.size();
8080                for (int ia=0; ia<NA; ia++) {
8081                    ProcessRecord p = apps.valueAt(ia);
8082                    if (p.thread != null && p.thread.asBinder() == app) {
8083                        return p;
8084                    }
8085                }
8086            }
8087
8088            Slog.w(TAG, "Can't find mystery application for " + reason
8089                    + " from pid=" + Binder.getCallingPid()
8090                    + " uid=" + Binder.getCallingUid() + ": " + app);
8091            return null;
8092        }
8093    }
8094
8095    /**
8096     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8097     * to append various headers to the dropbox log text.
8098     */
8099    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8100            StringBuilder sb) {
8101        // Watchdog thread ends up invoking this function (with
8102        // a null ProcessRecord) to add the stack file to dropbox.
8103        // Do not acquire a lock on this (am) in such cases, as it
8104        // could cause a potential deadlock, if and when watchdog
8105        // is invoked due to unavailability of lock on am and it
8106        // would prevent watchdog from killing system_server.
8107        if (process == null) {
8108            sb.append("Process: ").append(processName).append("\n");
8109            return;
8110        }
8111        // Note: ProcessRecord 'process' is guarded by the service
8112        // instance.  (notably process.pkgList, which could otherwise change
8113        // concurrently during execution of this method)
8114        synchronized (this) {
8115            sb.append("Process: ").append(processName).append("\n");
8116            int flags = process.info.flags;
8117            IPackageManager pm = AppGlobals.getPackageManager();
8118            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8119            for (String pkg : process.pkgList) {
8120                sb.append("Package: ").append(pkg);
8121                try {
8122                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8123                    if (pi != null) {
8124                        sb.append(" v").append(pi.versionCode);
8125                        if (pi.versionName != null) {
8126                            sb.append(" (").append(pi.versionName).append(")");
8127                        }
8128                    }
8129                } catch (RemoteException e) {
8130                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8131                }
8132                sb.append("\n");
8133            }
8134        }
8135    }
8136
8137    private static String processClass(ProcessRecord process) {
8138        if (process == null || process.pid == MY_PID) {
8139            return "system_server";
8140        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8141            return "system_app";
8142        } else {
8143            return "data_app";
8144        }
8145    }
8146
8147    /**
8148     * Write a description of an error (crash, WTF, ANR) to the drop box.
8149     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8150     * @param process which caused the error, null means the system server
8151     * @param activity which triggered the error, null if unknown
8152     * @param parent activity related to the error, null if unknown
8153     * @param subject line related to the error, null if absent
8154     * @param report in long form describing the error, null if absent
8155     * @param logFile to include in the report, null if none
8156     * @param crashInfo giving an application stack trace, null if absent
8157     */
8158    public void addErrorToDropBox(String eventType,
8159            ProcessRecord process, String processName, ActivityRecord activity,
8160            ActivityRecord parent, String subject,
8161            final String report, final File logFile,
8162            final ApplicationErrorReport.CrashInfo crashInfo) {
8163        // NOTE -- this must never acquire the ActivityManagerService lock,
8164        // otherwise the watchdog may be prevented from resetting the system.
8165
8166        final String dropboxTag = processClass(process) + "_" + eventType;
8167        final DropBoxManager dbox = (DropBoxManager)
8168                mContext.getSystemService(Context.DROPBOX_SERVICE);
8169
8170        // Exit early if the dropbox isn't configured to accept this report type.
8171        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8172
8173        final StringBuilder sb = new StringBuilder(1024);
8174        appendDropBoxProcessHeaders(process, processName, sb);
8175        if (activity != null) {
8176            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8177        }
8178        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8179            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8180        }
8181        if (parent != null && parent != activity) {
8182            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8183        }
8184        if (subject != null) {
8185            sb.append("Subject: ").append(subject).append("\n");
8186        }
8187        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8188        if (Debug.isDebuggerConnected()) {
8189            sb.append("Debugger: Connected\n");
8190        }
8191        sb.append("\n");
8192
8193        // Do the rest in a worker thread to avoid blocking the caller on I/O
8194        // (After this point, we shouldn't access AMS internal data structures.)
8195        Thread worker = new Thread("Error dump: " + dropboxTag) {
8196            @Override
8197            public void run() {
8198                if (report != null) {
8199                    sb.append(report);
8200                }
8201                if (logFile != null) {
8202                    try {
8203                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8204                    } catch (IOException e) {
8205                        Slog.e(TAG, "Error reading " + logFile, e);
8206                    }
8207                }
8208                if (crashInfo != null && crashInfo.stackTrace != null) {
8209                    sb.append(crashInfo.stackTrace);
8210                }
8211
8212                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8213                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8214                if (lines > 0) {
8215                    sb.append("\n");
8216
8217                    // Merge several logcat streams, and take the last N lines
8218                    InputStreamReader input = null;
8219                    try {
8220                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8221                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8222                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8223
8224                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8225                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8226                        input = new InputStreamReader(logcat.getInputStream());
8227
8228                        int num;
8229                        char[] buf = new char[8192];
8230                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8231                    } catch (IOException e) {
8232                        Slog.e(TAG, "Error running logcat", e);
8233                    } finally {
8234                        if (input != null) try { input.close(); } catch (IOException e) {}
8235                    }
8236                }
8237
8238                dbox.addText(dropboxTag, sb.toString());
8239            }
8240        };
8241
8242        if (process == null) {
8243            // If process is null, we are being called from some internal code
8244            // and may be about to die -- run this synchronously.
8245            worker.run();
8246        } else {
8247            worker.start();
8248        }
8249    }
8250
8251    /**
8252     * Bring up the "unexpected error" dialog box for a crashing app.
8253     * Deal with edge cases (intercepts from instrumented applications,
8254     * ActivityController, error intent receivers, that sort of thing).
8255     * @param r the application crashing
8256     * @param crashInfo describing the failure
8257     */
8258    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8259        long timeMillis = System.currentTimeMillis();
8260        String shortMsg = crashInfo.exceptionClassName;
8261        String longMsg = crashInfo.exceptionMessage;
8262        String stackTrace = crashInfo.stackTrace;
8263        if (shortMsg != null && longMsg != null) {
8264            longMsg = shortMsg + ": " + longMsg;
8265        } else if (shortMsg != null) {
8266            longMsg = shortMsg;
8267        }
8268
8269        AppErrorResult result = new AppErrorResult();
8270        synchronized (this) {
8271            if (mController != null) {
8272                try {
8273                    String name = r != null ? r.processName : null;
8274                    int pid = r != null ? r.pid : Binder.getCallingPid();
8275                    if (!mController.appCrashed(name, pid,
8276                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8277                        Slog.w(TAG, "Force-killing crashed app " + name
8278                                + " at watcher's request");
8279                        Process.killProcess(pid);
8280                        return;
8281                    }
8282                } catch (RemoteException e) {
8283                    mController = null;
8284                }
8285            }
8286
8287            final long origId = Binder.clearCallingIdentity();
8288
8289            // If this process is running instrumentation, finish it.
8290            if (r != null && r.instrumentationClass != null) {
8291                Slog.w(TAG, "Error in app " + r.processName
8292                      + " running instrumentation " + r.instrumentationClass + ":");
8293                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8294                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8295                Bundle info = new Bundle();
8296                info.putString("shortMsg", shortMsg);
8297                info.putString("longMsg", longMsg);
8298                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8299                Binder.restoreCallingIdentity(origId);
8300                return;
8301            }
8302
8303            // If we can't identify the process or it's already exceeded its crash quota,
8304            // quit right away without showing a crash dialog.
8305            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8306                Binder.restoreCallingIdentity(origId);
8307                return;
8308            }
8309
8310            Message msg = Message.obtain();
8311            msg.what = SHOW_ERROR_MSG;
8312            HashMap data = new HashMap();
8313            data.put("result", result);
8314            data.put("app", r);
8315            msg.obj = data;
8316            mHandler.sendMessage(msg);
8317
8318            Binder.restoreCallingIdentity(origId);
8319        }
8320
8321        int res = result.get();
8322
8323        Intent appErrorIntent = null;
8324        synchronized (this) {
8325            if (r != null && !r.isolated) {
8326                // XXX Can't keep track of crash time for isolated processes,
8327                // since they don't have a persistent identity.
8328                mProcessCrashTimes.put(r.info.processName, r.uid,
8329                        SystemClock.uptimeMillis());
8330            }
8331            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8332                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8333            }
8334        }
8335
8336        if (appErrorIntent != null) {
8337            try {
8338                mContext.startActivity(appErrorIntent);
8339            } catch (ActivityNotFoundException e) {
8340                Slog.w(TAG, "bug report receiver dissappeared", e);
8341            }
8342        }
8343    }
8344
8345    Intent createAppErrorIntentLocked(ProcessRecord r,
8346            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8347        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8348        if (report == null) {
8349            return null;
8350        }
8351        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8352        result.setComponent(r.errorReportReceiver);
8353        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8354        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8355        return result;
8356    }
8357
8358    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8359            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8360        if (r.errorReportReceiver == null) {
8361            return null;
8362        }
8363
8364        if (!r.crashing && !r.notResponding) {
8365            return null;
8366        }
8367
8368        ApplicationErrorReport report = new ApplicationErrorReport();
8369        report.packageName = r.info.packageName;
8370        report.installerPackageName = r.errorReportReceiver.getPackageName();
8371        report.processName = r.processName;
8372        report.time = timeMillis;
8373        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8374
8375        if (r.crashing) {
8376            report.type = ApplicationErrorReport.TYPE_CRASH;
8377            report.crashInfo = crashInfo;
8378        } else if (r.notResponding) {
8379            report.type = ApplicationErrorReport.TYPE_ANR;
8380            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8381
8382            report.anrInfo.activity = r.notRespondingReport.tag;
8383            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8384            report.anrInfo.info = r.notRespondingReport.longMsg;
8385        }
8386
8387        return report;
8388    }
8389
8390    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8391        enforceNotIsolatedCaller("getProcessesInErrorState");
8392        // assume our apps are happy - lazy create the list
8393        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8394
8395        synchronized (this) {
8396
8397            // iterate across all processes
8398            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8399                ProcessRecord app = mLruProcesses.get(i);
8400                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8401                    // This one's in trouble, so we'll generate a report for it
8402                    // crashes are higher priority (in case there's a crash *and* an anr)
8403                    ActivityManager.ProcessErrorStateInfo report = null;
8404                    if (app.crashing) {
8405                        report = app.crashingReport;
8406                    } else if (app.notResponding) {
8407                        report = app.notRespondingReport;
8408                    }
8409
8410                    if (report != null) {
8411                        if (errList == null) {
8412                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8413                        }
8414                        errList.add(report);
8415                    } else {
8416                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8417                                " crashing = " + app.crashing +
8418                                " notResponding = " + app.notResponding);
8419                    }
8420                }
8421            }
8422        }
8423
8424        return errList;
8425    }
8426
8427    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8428        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8429            if (currApp != null) {
8430                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8431            }
8432            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8433        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8434            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8435        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8436            if (currApp != null) {
8437                currApp.lru = 0;
8438            }
8439            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8440        } else if (adj >= ProcessList.SERVICE_ADJ) {
8441            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8442        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8443            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8444        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8445            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8446        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8447            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8448        } else {
8449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8450        }
8451    }
8452
8453    private void fillInProcMemInfo(ProcessRecord app,
8454            ActivityManager.RunningAppProcessInfo outInfo) {
8455        outInfo.pid = app.pid;
8456        outInfo.uid = app.info.uid;
8457        if (mHeavyWeightProcess == app) {
8458            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8459        }
8460        if (app.persistent) {
8461            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8462        }
8463        outInfo.lastTrimLevel = app.trimMemoryLevel;
8464        int adj = app.curAdj;
8465        outInfo.importance = oomAdjToImportance(adj, outInfo);
8466        outInfo.importanceReasonCode = app.adjTypeCode;
8467    }
8468
8469    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8470        enforceNotIsolatedCaller("getRunningAppProcesses");
8471        // Lazy instantiation of list
8472        List<ActivityManager.RunningAppProcessInfo> runList = null;
8473        synchronized (this) {
8474            // Iterate across all processes
8475            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8476                ProcessRecord app = mLruProcesses.get(i);
8477                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8478                    // Generate process state info for running application
8479                    ActivityManager.RunningAppProcessInfo currApp =
8480                        new ActivityManager.RunningAppProcessInfo(app.processName,
8481                                app.pid, app.getPackageList());
8482                    fillInProcMemInfo(app, currApp);
8483                    if (app.adjSource instanceof ProcessRecord) {
8484                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8485                        currApp.importanceReasonImportance = oomAdjToImportance(
8486                                app.adjSourceOom, null);
8487                    } else if (app.adjSource instanceof ActivityRecord) {
8488                        ActivityRecord r = (ActivityRecord)app.adjSource;
8489                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8490                    }
8491                    if (app.adjTarget instanceof ComponentName) {
8492                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8493                    }
8494                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8495                    //        + " lru=" + currApp.lru);
8496                    if (runList == null) {
8497                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8498                    }
8499                    runList.add(currApp);
8500                }
8501            }
8502        }
8503        return runList;
8504    }
8505
8506    public List<ApplicationInfo> getRunningExternalApplications() {
8507        enforceNotIsolatedCaller("getRunningExternalApplications");
8508        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8509        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8510        if (runningApps != null && runningApps.size() > 0) {
8511            Set<String> extList = new HashSet<String>();
8512            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8513                if (app.pkgList != null) {
8514                    for (String pkg : app.pkgList) {
8515                        extList.add(pkg);
8516                    }
8517                }
8518            }
8519            IPackageManager pm = AppGlobals.getPackageManager();
8520            for (String pkg : extList) {
8521                try {
8522                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8523                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8524                        retList.add(info);
8525                    }
8526                } catch (RemoteException e) {
8527                }
8528            }
8529        }
8530        return retList;
8531    }
8532
8533    @Override
8534    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8535        enforceNotIsolatedCaller("getMyMemoryState");
8536        synchronized (this) {
8537            ProcessRecord proc;
8538            synchronized (mPidsSelfLocked) {
8539                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8540            }
8541            fillInProcMemInfo(proc, outInfo);
8542        }
8543    }
8544
8545    @Override
8546    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8547        if (checkCallingPermission(android.Manifest.permission.DUMP)
8548                != PackageManager.PERMISSION_GRANTED) {
8549            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8550                    + Binder.getCallingPid()
8551                    + ", uid=" + Binder.getCallingUid()
8552                    + " without permission "
8553                    + android.Manifest.permission.DUMP);
8554            return;
8555        }
8556
8557        boolean dumpAll = false;
8558        boolean dumpClient = false;
8559        String dumpPackage = null;
8560
8561        int opti = 0;
8562        while (opti < args.length) {
8563            String opt = args[opti];
8564            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8565                break;
8566            }
8567            opti++;
8568            if ("-a".equals(opt)) {
8569                dumpAll = true;
8570            } else if ("-c".equals(opt)) {
8571                dumpClient = true;
8572            } else if ("-h".equals(opt)) {
8573                pw.println("Activity manager dump options:");
8574                pw.println("  [-a] [-c] [-h] [cmd] ...");
8575                pw.println("  cmd may be one of:");
8576                pw.println("    a[ctivities]: activity stack state");
8577                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8578                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8579                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8580                pw.println("    o[om]: out of memory management");
8581                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8582                pw.println("    provider [COMP_SPEC]: provider client-side state");
8583                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8584                pw.println("    service [COMP_SPEC]: service client-side state");
8585                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8586                pw.println("    all: dump all activities");
8587                pw.println("    top: dump the top activity");
8588                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8589                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8590                pw.println("    a partial substring in a component name, a");
8591                pw.println("    hex object identifier.");
8592                pw.println("  -a: include all available server state.");
8593                pw.println("  -c: include client state.");
8594                return;
8595            } else {
8596                pw.println("Unknown argument: " + opt + "; use -h for help");
8597            }
8598        }
8599
8600        long origId = Binder.clearCallingIdentity();
8601        boolean more = false;
8602        // Is the caller requesting to dump a particular piece of data?
8603        if (opti < args.length) {
8604            String cmd = args[opti];
8605            opti++;
8606            if ("activities".equals(cmd) || "a".equals(cmd)) {
8607                synchronized (this) {
8608                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8609                }
8610            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8611                String[] newArgs;
8612                String name;
8613                if (opti >= args.length) {
8614                    name = null;
8615                    newArgs = EMPTY_STRING_ARRAY;
8616                } else {
8617                    name = args[opti];
8618                    opti++;
8619                    newArgs = new String[args.length - opti];
8620                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8621                            args.length - opti);
8622                }
8623                synchronized (this) {
8624                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8625                }
8626            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8627                String[] newArgs;
8628                String name;
8629                if (opti >= args.length) {
8630                    name = null;
8631                    newArgs = EMPTY_STRING_ARRAY;
8632                } else {
8633                    name = args[opti];
8634                    opti++;
8635                    newArgs = new String[args.length - opti];
8636                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8637                            args.length - opti);
8638                }
8639                synchronized (this) {
8640                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8641                }
8642            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8643                String[] newArgs;
8644                String name;
8645                if (opti >= args.length) {
8646                    name = null;
8647                    newArgs = EMPTY_STRING_ARRAY;
8648                } else {
8649                    name = args[opti];
8650                    opti++;
8651                    newArgs = new String[args.length - opti];
8652                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8653                            args.length - opti);
8654                }
8655                synchronized (this) {
8656                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8657                }
8658            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8659                synchronized (this) {
8660                    dumpOomLocked(fd, pw, args, opti, true);
8661                }
8662            } else if ("provider".equals(cmd)) {
8663                String[] newArgs;
8664                String name;
8665                if (opti >= args.length) {
8666                    name = null;
8667                    newArgs = EMPTY_STRING_ARRAY;
8668                } else {
8669                    name = args[opti];
8670                    opti++;
8671                    newArgs = new String[args.length - opti];
8672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8673                }
8674                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8675                    pw.println("No providers match: " + name);
8676                    pw.println("Use -h for help.");
8677                }
8678            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8679                synchronized (this) {
8680                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8681                }
8682            } else if ("service".equals(cmd)) {
8683                String[] newArgs;
8684                String name;
8685                if (opti >= args.length) {
8686                    name = null;
8687                    newArgs = EMPTY_STRING_ARRAY;
8688                } else {
8689                    name = args[opti];
8690                    opti++;
8691                    newArgs = new String[args.length - opti];
8692                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8693                            args.length - opti);
8694                }
8695                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8696                    pw.println("No services match: " + name);
8697                    pw.println("Use -h for help.");
8698                }
8699            } else if ("package".equals(cmd)) {
8700                String[] newArgs;
8701                if (opti >= args.length) {
8702                    pw.println("package: no package name specified");
8703                    pw.println("Use -h for help.");
8704                } else {
8705                    dumpPackage = args[opti];
8706                    opti++;
8707                    newArgs = new String[args.length - opti];
8708                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8709                            args.length - opti);
8710                    args = newArgs;
8711                    opti = 0;
8712                    more = true;
8713                }
8714            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8715                synchronized (this) {
8716                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8717                }
8718            } else {
8719                // Dumping a single activity?
8720                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8721                    pw.println("Bad activity command, or no activities match: " + cmd);
8722                    pw.println("Use -h for help.");
8723                }
8724            }
8725            if (!more) {
8726                Binder.restoreCallingIdentity(origId);
8727                return;
8728            }
8729        }
8730
8731        // No piece of data specified, dump everything.
8732        synchronized (this) {
8733            boolean needSep;
8734            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8735            if (needSep) {
8736                pw.println(" ");
8737            }
8738            if (dumpAll) {
8739                pw.println("-------------------------------------------------------------------------------");
8740            }
8741            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8742            if (needSep) {
8743                pw.println(" ");
8744            }
8745            if (dumpAll) {
8746                pw.println("-------------------------------------------------------------------------------");
8747            }
8748            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8749            if (needSep) {
8750                pw.println(" ");
8751            }
8752            if (dumpAll) {
8753                pw.println("-------------------------------------------------------------------------------");
8754            }
8755            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8756            if (needSep) {
8757                pw.println(" ");
8758            }
8759            if (dumpAll) {
8760                pw.println("-------------------------------------------------------------------------------");
8761            }
8762            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8763            if (needSep) {
8764                pw.println(" ");
8765            }
8766            if (dumpAll) {
8767                pw.println("-------------------------------------------------------------------------------");
8768            }
8769            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8770        }
8771        Binder.restoreCallingIdentity(origId);
8772    }
8773
8774    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8775            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8776        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8777        pw.println("  Main stack:");
8778        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8779                dumpPackage);
8780        pw.println(" ");
8781        pw.println("  Running activities (most recent first):");
8782        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8783                dumpPackage);
8784        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8785            pw.println(" ");
8786            pw.println("  Activities waiting for another to become visible:");
8787            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8788                    !dumpAll, false, dumpPackage);
8789        }
8790        if (mMainStack.mStoppingActivities.size() > 0) {
8791            pw.println(" ");
8792            pw.println("  Activities waiting to stop:");
8793            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8794                    !dumpAll, false, dumpPackage);
8795        }
8796        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8797            pw.println(" ");
8798            pw.println("  Activities waiting to sleep:");
8799            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8800                    !dumpAll, false, dumpPackage);
8801        }
8802        if (mMainStack.mFinishingActivities.size() > 0) {
8803            pw.println(" ");
8804            pw.println("  Activities waiting to finish:");
8805            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8806                    !dumpAll, false, dumpPackage);
8807        }
8808
8809        pw.println(" ");
8810        if (mMainStack.mPausingActivity != null) {
8811            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8812        }
8813        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8814        pw.println("  mFocusedActivity: " + mFocusedActivity);
8815        if (dumpAll) {
8816            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8817            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8818            pw.println("  mDismissKeyguardOnNextActivity: "
8819                    + mMainStack.mDismissKeyguardOnNextActivity);
8820        }
8821
8822        if (mRecentTasks.size() > 0) {
8823            pw.println();
8824            pw.println("  Recent tasks:");
8825
8826            final int N = mRecentTasks.size();
8827            for (int i=0; i<N; i++) {
8828                TaskRecord tr = mRecentTasks.get(i);
8829                if (dumpPackage != null) {
8830                    if (tr.realActivity == null ||
8831                            !dumpPackage.equals(tr.realActivity)) {
8832                        continue;
8833                    }
8834                }
8835                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8836                        pw.println(tr);
8837                if (dumpAll) {
8838                    mRecentTasks.get(i).dump(pw, "    ");
8839                }
8840            }
8841        }
8842
8843        if (dumpAll) {
8844            pw.println(" ");
8845            pw.println("  mCurTask: " + mCurTask);
8846        }
8847
8848        return true;
8849    }
8850
8851    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8852            int opti, boolean dumpAll, String dumpPackage) {
8853        boolean needSep = false;
8854        int numPers = 0;
8855
8856        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8857
8858        if (dumpAll) {
8859            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8860                final int NA = procs.size();
8861                for (int ia=0; ia<NA; ia++) {
8862                    ProcessRecord r = procs.valueAt(ia);
8863                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8864                        continue;
8865                    }
8866                    if (!needSep) {
8867                        pw.println("  All known processes:");
8868                        needSep = true;
8869                    }
8870                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8871                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8872                        pw.print(" "); pw.println(r);
8873                    r.dump(pw, "    ");
8874                    if (r.persistent) {
8875                        numPers++;
8876                    }
8877                }
8878            }
8879        }
8880
8881        if (mIsolatedProcesses.size() > 0) {
8882            if (needSep) pw.println(" ");
8883            needSep = true;
8884            pw.println("  Isolated process list (sorted by uid):");
8885            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8886                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8887                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8888                    continue;
8889                }
8890                pw.println(String.format("%sIsolated #%2d: %s",
8891                        "    ", i, r.toString()));
8892            }
8893        }
8894
8895        if (mLruProcesses.size() > 0) {
8896            if (needSep) pw.println(" ");
8897            needSep = true;
8898            pw.println("  Process LRU list (sorted by oom_adj):");
8899            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8900                    "Proc", "PERS", false, dumpPackage);
8901            needSep = true;
8902        }
8903
8904        if (dumpAll) {
8905            synchronized (mPidsSelfLocked) {
8906                boolean printed = false;
8907                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8908                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8909                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8910                        continue;
8911                    }
8912                    if (!printed) {
8913                        if (needSep) pw.println(" ");
8914                        needSep = true;
8915                        pw.println("  PID mappings:");
8916                        printed = true;
8917                    }
8918                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8919                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8920                }
8921            }
8922        }
8923
8924        if (mForegroundProcesses.size() > 0) {
8925            synchronized (mPidsSelfLocked) {
8926                boolean printed = false;
8927                for (int i=0; i<mForegroundProcesses.size(); i++) {
8928                    ProcessRecord r = mPidsSelfLocked.get(
8929                            mForegroundProcesses.valueAt(i).pid);
8930                    if (dumpPackage != null && (r == null
8931                            || !dumpPackage.equals(r.info.packageName))) {
8932                        continue;
8933                    }
8934                    if (!printed) {
8935                        if (needSep) pw.println(" ");
8936                        needSep = true;
8937                        pw.println("  Foreground Processes:");
8938                        printed = true;
8939                    }
8940                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8941                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8942                }
8943            }
8944        }
8945
8946        if (mPersistentStartingProcesses.size() > 0) {
8947            if (needSep) pw.println(" ");
8948            needSep = true;
8949            pw.println("  Persisent processes that are starting:");
8950            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8951                    "Starting Norm", "Restarting PERS", dumpPackage);
8952        }
8953
8954        if (mRemovedProcesses.size() > 0) {
8955            if (needSep) pw.println(" ");
8956            needSep = true;
8957            pw.println("  Processes that are being removed:");
8958            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8959                    "Removed Norm", "Removed PERS", dumpPackage);
8960        }
8961
8962        if (mProcessesOnHold.size() > 0) {
8963            if (needSep) pw.println(" ");
8964            needSep = true;
8965            pw.println("  Processes that are on old until the system is ready:");
8966            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8967                    "OnHold Norm", "OnHold PERS", dumpPackage);
8968        }
8969
8970        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8971
8972        if (mProcessCrashTimes.getMap().size() > 0) {
8973            boolean printed = false;
8974            long now = SystemClock.uptimeMillis();
8975            for (Map.Entry<String, SparseArray<Long>> procs
8976                    : mProcessCrashTimes.getMap().entrySet()) {
8977                String pname = procs.getKey();
8978                SparseArray<Long> uids = procs.getValue();
8979                final int N = uids.size();
8980                for (int i=0; i<N; i++) {
8981                    int puid = uids.keyAt(i);
8982                    ProcessRecord r = mProcessNames.get(pname, puid);
8983                    if (dumpPackage != null && (r == null
8984                            || !dumpPackage.equals(r.info.packageName))) {
8985                        continue;
8986                    }
8987                    if (!printed) {
8988                        if (needSep) pw.println(" ");
8989                        needSep = true;
8990                        pw.println("  Time since processes crashed:");
8991                        printed = true;
8992                    }
8993                    pw.print("    Process "); pw.print(pname);
8994                            pw.print(" uid "); pw.print(puid);
8995                            pw.print(": last crashed ");
8996                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8997                            pw.println(" ago");
8998                }
8999            }
9000        }
9001
9002        if (mBadProcesses.getMap().size() > 0) {
9003            boolean printed = false;
9004            for (Map.Entry<String, SparseArray<Long>> procs
9005                    : mBadProcesses.getMap().entrySet()) {
9006                String pname = procs.getKey();
9007                SparseArray<Long> uids = procs.getValue();
9008                final int N = uids.size();
9009                for (int i=0; i<N; i++) {
9010                    int puid = uids.keyAt(i);
9011                    ProcessRecord r = mProcessNames.get(pname, puid);
9012                    if (dumpPackage != null && (r == null
9013                            || !dumpPackage.equals(r.info.packageName))) {
9014                        continue;
9015                    }
9016                    if (!printed) {
9017                        if (needSep) pw.println(" ");
9018                        needSep = true;
9019                        pw.println("  Bad processes:");
9020                    }
9021                    pw.print("    Bad process "); pw.print(pname);
9022                            pw.print(" uid "); pw.print(puid);
9023                            pw.print(": crashed at time ");
9024                            pw.println(uids.valueAt(i));
9025                }
9026            }
9027        }
9028
9029        pw.println();
9030        pw.println("  mHomeProcess: " + mHomeProcess);
9031        pw.println("  mPreviousProcess: " + mPreviousProcess);
9032        if (dumpAll) {
9033            StringBuilder sb = new StringBuilder(128);
9034            sb.append("  mPreviousProcessVisibleTime: ");
9035            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9036            pw.println(sb);
9037        }
9038        if (mHeavyWeightProcess != null) {
9039            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9040        }
9041        pw.println("  mConfiguration: " + mConfiguration);
9042        if (dumpAll) {
9043            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9044            if (mCompatModePackages.getPackages().size() > 0) {
9045                boolean printed = false;
9046                for (Map.Entry<String, Integer> entry
9047                        : mCompatModePackages.getPackages().entrySet()) {
9048                    String pkg = entry.getKey();
9049                    int mode = entry.getValue();
9050                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9051                        continue;
9052                    }
9053                    if (!printed) {
9054                        pw.println("  mScreenCompatPackages:");
9055                        printed = true;
9056                    }
9057                    pw.print("    "); pw.print(pkg); pw.print(": ");
9058                            pw.print(mode); pw.println();
9059                }
9060            }
9061        }
9062        if (mSleeping || mWentToSleep || mLockScreenShown) {
9063            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9064                    + " mLockScreenShown " + mLockScreenShown);
9065        }
9066        if (mShuttingDown) {
9067            pw.println("  mShuttingDown=" + mShuttingDown);
9068        }
9069        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9070                || mOrigWaitForDebugger) {
9071            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9072                    + " mDebugTransient=" + mDebugTransient
9073                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9074        }
9075        if (mOpenGlTraceApp != null) {
9076            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9077        }
9078        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9079                || mProfileFd != null) {
9080            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9081            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9082            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9083                    + mAutoStopProfiler);
9084        }
9085        if (mAlwaysFinishActivities || mController != null) {
9086            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9087                    + " mController=" + mController);
9088        }
9089        if (dumpAll) {
9090            pw.println("  Total persistent processes: " + numPers);
9091            pw.println("  mStartRunning=" + mStartRunning
9092                    + " mProcessesReady=" + mProcessesReady
9093                    + " mSystemReady=" + mSystemReady);
9094            pw.println("  mBooting=" + mBooting
9095                    + " mBooted=" + mBooted
9096                    + " mFactoryTest=" + mFactoryTest);
9097            pw.print("  mLastPowerCheckRealtime=");
9098                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9099                    pw.println("");
9100            pw.print("  mLastPowerCheckUptime=");
9101                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9102                    pw.println("");
9103            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9104            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9105            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9106            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9107                    + " mNumHiddenProcs=" + mNumHiddenProcs
9108                    + " mNumServiceProcs=" + mNumServiceProcs
9109                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9110        }
9111
9112        return true;
9113    }
9114
9115    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9116            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9117        if (mProcessesToGc.size() > 0) {
9118            boolean printed = false;
9119            long now = SystemClock.uptimeMillis();
9120            for (int i=0; i<mProcessesToGc.size(); i++) {
9121                ProcessRecord proc = mProcessesToGc.get(i);
9122                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9123                    continue;
9124                }
9125                if (!printed) {
9126                    if (needSep) pw.println(" ");
9127                    needSep = true;
9128                    pw.println("  Processes that are waiting to GC:");
9129                    printed = true;
9130                }
9131                pw.print("    Process "); pw.println(proc);
9132                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9133                        pw.print(", last gced=");
9134                        pw.print(now-proc.lastRequestedGc);
9135                        pw.print(" ms ago, last lowMem=");
9136                        pw.print(now-proc.lastLowMemory);
9137                        pw.println(" ms ago");
9138
9139            }
9140        }
9141        return needSep;
9142    }
9143
9144    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9145            int opti, boolean dumpAll) {
9146        boolean needSep = false;
9147
9148        if (mLruProcesses.size() > 0) {
9149            if (needSep) pw.println(" ");
9150            needSep = true;
9151            pw.println("  OOM levels:");
9152            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9153            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9154            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9155            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9156            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9157            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9158            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9159            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9160            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9161            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9162            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9163            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9164            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9165
9166            if (needSep) pw.println(" ");
9167            needSep = true;
9168            pw.println("  Process OOM control:");
9169            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9170                    "Proc", "PERS", true, null);
9171            needSep = true;
9172        }
9173
9174        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9175
9176        pw.println();
9177        pw.println("  mHomeProcess: " + mHomeProcess);
9178        pw.println("  mPreviousProcess: " + mPreviousProcess);
9179        if (mHeavyWeightProcess != null) {
9180            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9181        }
9182
9183        return true;
9184    }
9185
9186    /**
9187     * There are three ways to call this:
9188     *  - no provider specified: dump all the providers
9189     *  - a flattened component name that matched an existing provider was specified as the
9190     *    first arg: dump that one provider
9191     *  - the first arg isn't the flattened component name of an existing provider:
9192     *    dump all providers whose component contains the first arg as a substring
9193     */
9194    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9195            int opti, boolean dumpAll) {
9196        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9197    }
9198
9199    static class ItemMatcher {
9200        ArrayList<ComponentName> components;
9201        ArrayList<String> strings;
9202        ArrayList<Integer> objects;
9203        boolean all;
9204
9205        ItemMatcher() {
9206            all = true;
9207        }
9208
9209        void build(String name) {
9210            ComponentName componentName = ComponentName.unflattenFromString(name);
9211            if (componentName != null) {
9212                if (components == null) {
9213                    components = new ArrayList<ComponentName>();
9214                }
9215                components.add(componentName);
9216                all = false;
9217            } else {
9218                int objectId = 0;
9219                // Not a '/' separated full component name; maybe an object ID?
9220                try {
9221                    objectId = Integer.parseInt(name, 16);
9222                    if (objects == null) {
9223                        objects = new ArrayList<Integer>();
9224                    }
9225                    objects.add(objectId);
9226                    all = false;
9227                } catch (RuntimeException e) {
9228                    // Not an integer; just do string match.
9229                    if (strings == null) {
9230                        strings = new ArrayList<String>();
9231                    }
9232                    strings.add(name);
9233                    all = false;
9234                }
9235            }
9236        }
9237
9238        int build(String[] args, int opti) {
9239            for (; opti<args.length; opti++) {
9240                String name = args[opti];
9241                if ("--".equals(name)) {
9242                    return opti+1;
9243                }
9244                build(name);
9245            }
9246            return opti;
9247        }
9248
9249        boolean match(Object object, ComponentName comp) {
9250            if (all) {
9251                return true;
9252            }
9253            if (components != null) {
9254                for (int i=0; i<components.size(); i++) {
9255                    if (components.get(i).equals(comp)) {
9256                        return true;
9257                    }
9258                }
9259            }
9260            if (objects != null) {
9261                for (int i=0; i<objects.size(); i++) {
9262                    if (System.identityHashCode(object) == objects.get(i)) {
9263                        return true;
9264                    }
9265                }
9266            }
9267            if (strings != null) {
9268                String flat = comp.flattenToString();
9269                for (int i=0; i<strings.size(); i++) {
9270                    if (flat.contains(strings.get(i))) {
9271                        return true;
9272                    }
9273                }
9274            }
9275            return false;
9276        }
9277    }
9278
9279    /**
9280     * There are three things that cmd can be:
9281     *  - a flattened component name that matches an existing activity
9282     *  - the cmd arg isn't the flattened component name of an existing activity:
9283     *    dump all activity whose component contains the cmd as a substring
9284     *  - A hex number of the ActivityRecord object instance.
9285     */
9286    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9287            int opti, boolean dumpAll) {
9288        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9289
9290        if ("all".equals(name)) {
9291            synchronized (this) {
9292                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9293                    activities.add(r1);
9294                }
9295            }
9296        } else if ("top".equals(name)) {
9297            synchronized (this) {
9298                final int N = mMainStack.mHistory.size();
9299                if (N > 0) {
9300                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9301                }
9302            }
9303        } else {
9304            ItemMatcher matcher = new ItemMatcher();
9305            matcher.build(name);
9306
9307            synchronized (this) {
9308                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9309                    if (matcher.match(r1, r1.intent.getComponent())) {
9310                        activities.add(r1);
9311                    }
9312                }
9313            }
9314        }
9315
9316        if (activities.size() <= 0) {
9317            return false;
9318        }
9319
9320        String[] newArgs = new String[args.length - opti];
9321        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9322
9323        TaskRecord lastTask = null;
9324        boolean needSep = false;
9325        for (int i=activities.size()-1; i>=0; i--) {
9326            ActivityRecord r = (ActivityRecord)activities.get(i);
9327            if (needSep) {
9328                pw.println();
9329            }
9330            needSep = true;
9331            synchronized (this) {
9332                if (lastTask != r.task) {
9333                    lastTask = r.task;
9334                    pw.print("TASK "); pw.print(lastTask.affinity);
9335                            pw.print(" id="); pw.println(lastTask.taskId);
9336                    if (dumpAll) {
9337                        lastTask.dump(pw, "  ");
9338                    }
9339                }
9340            }
9341            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9342        }
9343        return true;
9344    }
9345
9346    /**
9347     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9348     * there is a thread associated with the activity.
9349     */
9350    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9351            final ActivityRecord r, String[] args, boolean dumpAll) {
9352        String innerPrefix = prefix + "  ";
9353        synchronized (this) {
9354            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9355                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9356                    pw.print(" pid=");
9357                    if (r.app != null) pw.println(r.app.pid);
9358                    else pw.println("(not running)");
9359            if (dumpAll) {
9360                r.dump(pw, innerPrefix);
9361            }
9362        }
9363        if (r.app != null && r.app.thread != null) {
9364            // flush anything that is already in the PrintWriter since the thread is going
9365            // to write to the file descriptor directly
9366            pw.flush();
9367            try {
9368                TransferPipe tp = new TransferPipe();
9369                try {
9370                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9371                            r.appToken, innerPrefix, args);
9372                    tp.go(fd);
9373                } finally {
9374                    tp.kill();
9375                }
9376            } catch (IOException e) {
9377                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9378            } catch (RemoteException e) {
9379                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9380            }
9381        }
9382    }
9383
9384    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9385            int opti, boolean dumpAll, String dumpPackage) {
9386        boolean needSep = false;
9387
9388        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9389        if (dumpAll) {
9390            if (mRegisteredReceivers.size() > 0) {
9391                boolean printed = false;
9392                Iterator it = mRegisteredReceivers.values().iterator();
9393                while (it.hasNext()) {
9394                    ReceiverList r = (ReceiverList)it.next();
9395                    if (dumpPackage != null && (r.app == null ||
9396                            !dumpPackage.equals(r.app.info.packageName))) {
9397                        continue;
9398                    }
9399                    if (!printed) {
9400                        pw.println("  Registered Receivers:");
9401                        needSep = true;
9402                        printed = true;
9403                    }
9404                    pw.print("  * "); pw.println(r);
9405                    r.dump(pw, "    ");
9406                }
9407            }
9408
9409            if (mReceiverResolver.dump(pw, needSep ?
9410                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9411                    "    ", dumpPackage, false)) {
9412                needSep = true;
9413            }
9414        }
9415
9416        for (BroadcastQueue q : mBroadcastQueues) {
9417            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9418        }
9419
9420        needSep = true;
9421
9422        if (mStickyBroadcasts != null && dumpPackage == null) {
9423            if (needSep) {
9424                pw.println();
9425            }
9426            needSep = true;
9427            pw.println("  Sticky broadcasts:");
9428            StringBuilder sb = new StringBuilder(128);
9429            for (Map.Entry<String, ArrayList<Intent>> ent
9430                    : mStickyBroadcasts.entrySet()) {
9431                pw.print("  * Sticky action "); pw.print(ent.getKey());
9432                if (dumpAll) {
9433                    pw.println(":");
9434                    ArrayList<Intent> intents = ent.getValue();
9435                    final int N = intents.size();
9436                    for (int i=0; i<N; i++) {
9437                        sb.setLength(0);
9438                        sb.append("    Intent: ");
9439                        intents.get(i).toShortString(sb, false, true, false, false);
9440                        pw.println(sb.toString());
9441                        Bundle bundle = intents.get(i).getExtras();
9442                        if (bundle != null) {
9443                            pw.print("      ");
9444                            pw.println(bundle.toString());
9445                        }
9446                    }
9447                } else {
9448                    pw.println("");
9449                }
9450            }
9451            needSep = true;
9452        }
9453
9454        if (dumpAll) {
9455            pw.println();
9456            for (BroadcastQueue queue : mBroadcastQueues) {
9457                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9458                        + queue.mBroadcastsScheduled);
9459            }
9460            pw.println("  mHandler:");
9461            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9462            needSep = true;
9463        }
9464
9465        return needSep;
9466    }
9467
9468    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9469            int opti, boolean dumpAll, String dumpPackage) {
9470        boolean needSep = true;
9471
9472        ItemMatcher matcher = new ItemMatcher();
9473        matcher.build(args, opti);
9474
9475        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9476
9477        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9478
9479        if (mLaunchingProviders.size() > 0) {
9480            boolean printed = false;
9481            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9482                ContentProviderRecord r = mLaunchingProviders.get(i);
9483                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9484                    continue;
9485                }
9486                if (!printed) {
9487                    if (needSep) pw.println(" ");
9488                    needSep = true;
9489                    pw.println("  Launching content providers:");
9490                    printed = true;
9491                }
9492                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9493                        pw.println(r);
9494            }
9495        }
9496
9497        if (mGrantedUriPermissions.size() > 0) {
9498            if (needSep) pw.println();
9499            needSep = true;
9500            pw.println("Granted Uri Permissions:");
9501            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9502                int uid = mGrantedUriPermissions.keyAt(i);
9503                HashMap<Uri, UriPermission> perms
9504                        = mGrantedUriPermissions.valueAt(i);
9505                pw.print("  * UID "); pw.print(uid);
9506                        pw.println(" holds:");
9507                for (UriPermission perm : perms.values()) {
9508                    pw.print("    "); pw.println(perm);
9509                    if (dumpAll) {
9510                        perm.dump(pw, "      ");
9511                    }
9512                }
9513            }
9514            needSep = true;
9515        }
9516
9517        return needSep;
9518    }
9519
9520    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9521            int opti, boolean dumpAll, String dumpPackage) {
9522        boolean needSep = false;
9523
9524        if (mIntentSenderRecords.size() > 0) {
9525            boolean printed = false;
9526            Iterator<WeakReference<PendingIntentRecord>> it
9527                    = mIntentSenderRecords.values().iterator();
9528            while (it.hasNext()) {
9529                WeakReference<PendingIntentRecord> ref = it.next();
9530                PendingIntentRecord rec = ref != null ? ref.get(): null;
9531                if (dumpPackage != null && (rec == null
9532                        || !dumpPackage.equals(rec.key.packageName))) {
9533                    continue;
9534                }
9535                if (!printed) {
9536                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9537                    printed = true;
9538                }
9539                needSep = true;
9540                if (rec != null) {
9541                    pw.print("  * "); pw.println(rec);
9542                    if (dumpAll) {
9543                        rec.dump(pw, "    ");
9544                    }
9545                } else {
9546                    pw.print("  * "); pw.println(ref);
9547                }
9548            }
9549        }
9550
9551        return needSep;
9552    }
9553
9554    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9555            String prefix, String label, boolean complete, boolean brief, boolean client,
9556            String dumpPackage) {
9557        TaskRecord lastTask = null;
9558        boolean needNL = false;
9559        final String innerPrefix = prefix + "      ";
9560        final String[] args = new String[0];
9561        for (int i=list.size()-1; i>=0; i--) {
9562            final ActivityRecord r = (ActivityRecord)list.get(i);
9563            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9564                continue;
9565            }
9566            final boolean full = !brief && (complete || !r.isInHistory());
9567            if (needNL) {
9568                pw.println(" ");
9569                needNL = false;
9570            }
9571            if (lastTask != r.task) {
9572                lastTask = r.task;
9573                pw.print(prefix);
9574                pw.print(full ? "* " : "  ");
9575                pw.println(lastTask);
9576                if (full) {
9577                    lastTask.dump(pw, prefix + "  ");
9578                } else if (complete) {
9579                    // Complete + brief == give a summary.  Isn't that obvious?!?
9580                    if (lastTask.intent != null) {
9581                        pw.print(prefix); pw.print("  ");
9582                                pw.println(lastTask.intent.toInsecureStringWithClip());
9583                    }
9584                }
9585            }
9586            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9587            pw.print(" #"); pw.print(i); pw.print(": ");
9588            pw.println(r);
9589            if (full) {
9590                r.dump(pw, innerPrefix);
9591            } else if (complete) {
9592                // Complete + brief == give a summary.  Isn't that obvious?!?
9593                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9594                if (r.app != null) {
9595                    pw.print(innerPrefix); pw.println(r.app);
9596                }
9597            }
9598            if (client && r.app != null && r.app.thread != null) {
9599                // flush anything that is already in the PrintWriter since the thread is going
9600                // to write to the file descriptor directly
9601                pw.flush();
9602                try {
9603                    TransferPipe tp = new TransferPipe();
9604                    try {
9605                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9606                                r.appToken, innerPrefix, args);
9607                        // Short timeout, since blocking here can
9608                        // deadlock with the application.
9609                        tp.go(fd, 2000);
9610                    } finally {
9611                        tp.kill();
9612                    }
9613                } catch (IOException e) {
9614                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9615                } catch (RemoteException e) {
9616                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9617                }
9618                needNL = true;
9619            }
9620        }
9621    }
9622
9623    private static String buildOomTag(String prefix, String space, int val, int base) {
9624        if (val == base) {
9625            if (space == null) return prefix;
9626            return prefix + "  ";
9627        }
9628        return prefix + "+" + Integer.toString(val-base);
9629    }
9630
9631    private static final int dumpProcessList(PrintWriter pw,
9632            ActivityManagerService service, List list,
9633            String prefix, String normalLabel, String persistentLabel,
9634            String dumpPackage) {
9635        int numPers = 0;
9636        final int N = list.size()-1;
9637        for (int i=N; i>=0; i--) {
9638            ProcessRecord r = (ProcessRecord)list.get(i);
9639            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9640                continue;
9641            }
9642            pw.println(String.format("%s%s #%2d: %s",
9643                    prefix, (r.persistent ? persistentLabel : normalLabel),
9644                    i, r.toString()));
9645            if (r.persistent) {
9646                numPers++;
9647            }
9648        }
9649        return numPers;
9650    }
9651
9652    private static final boolean dumpProcessOomList(PrintWriter pw,
9653            ActivityManagerService service, List<ProcessRecord> origList,
9654            String prefix, String normalLabel, String persistentLabel,
9655            boolean inclDetails, String dumpPackage) {
9656
9657        ArrayList<Pair<ProcessRecord, Integer>> list
9658                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9659        for (int i=0; i<origList.size(); i++) {
9660            ProcessRecord r = origList.get(i);
9661            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9662                continue;
9663            }
9664            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9665        }
9666
9667        if (list.size() <= 0) {
9668            return false;
9669        }
9670
9671        Comparator<Pair<ProcessRecord, Integer>> comparator
9672                = new Comparator<Pair<ProcessRecord, Integer>>() {
9673            @Override
9674            public int compare(Pair<ProcessRecord, Integer> object1,
9675                    Pair<ProcessRecord, Integer> object2) {
9676                if (object1.first.setAdj != object2.first.setAdj) {
9677                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9678                }
9679                if (object1.second.intValue() != object2.second.intValue()) {
9680                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9681                }
9682                return 0;
9683            }
9684        };
9685
9686        Collections.sort(list, comparator);
9687
9688        final long curRealtime = SystemClock.elapsedRealtime();
9689        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9690        final long curUptime = SystemClock.uptimeMillis();
9691        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9692
9693        for (int i=list.size()-1; i>=0; i--) {
9694            ProcessRecord r = list.get(i).first;
9695            String oomAdj;
9696            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9697                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9698            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9699                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9700            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9701                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9702            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9703                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9704            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9705                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9706            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9707                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9708            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9709                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9710            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9711                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9712            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9713                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9714            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9715                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9716            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9717                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9718            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9719                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9720            } else {
9721                oomAdj = Integer.toString(r.setAdj);
9722            }
9723            String schedGroup;
9724            switch (r.setSchedGroup) {
9725                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9726                    schedGroup = "B";
9727                    break;
9728                case Process.THREAD_GROUP_DEFAULT:
9729                    schedGroup = "F";
9730                    break;
9731                default:
9732                    schedGroup = Integer.toString(r.setSchedGroup);
9733                    break;
9734            }
9735            String foreground;
9736            if (r.foregroundActivities) {
9737                foreground = "A";
9738            } else if (r.foregroundServices) {
9739                foreground = "S";
9740            } else {
9741                foreground = " ";
9742            }
9743            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9744                    prefix, (r.persistent ? persistentLabel : normalLabel),
9745                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9746                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9747            if (r.adjSource != null || r.adjTarget != null) {
9748                pw.print(prefix);
9749                pw.print("    ");
9750                if (r.adjTarget instanceof ComponentName) {
9751                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9752                } else if (r.adjTarget != null) {
9753                    pw.print(r.adjTarget.toString());
9754                } else {
9755                    pw.print("{null}");
9756                }
9757                pw.print("<=");
9758                if (r.adjSource instanceof ProcessRecord) {
9759                    pw.print("Proc{");
9760                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9761                    pw.println("}");
9762                } else if (r.adjSource != null) {
9763                    pw.println(r.adjSource.toString());
9764                } else {
9765                    pw.println("{null}");
9766                }
9767            }
9768            if (inclDetails) {
9769                pw.print(prefix);
9770                pw.print("    ");
9771                pw.print("oom: max="); pw.print(r.maxAdj);
9772                pw.print(" hidden="); pw.print(r.hiddenAdj);
9773                pw.print(" empty="); pw.print(r.emptyAdj);
9774                pw.print(" curRaw="); pw.print(r.curRawAdj);
9775                pw.print(" setRaw="); pw.print(r.setRawAdj);
9776                pw.print(" cur="); pw.print(r.curAdj);
9777                pw.print(" set="); pw.println(r.setAdj);
9778                pw.print(prefix);
9779                pw.print("    ");
9780                pw.print("keeping="); pw.print(r.keeping);
9781                pw.print(" hidden="); pw.print(r.hidden);
9782                pw.print(" empty="); pw.print(r.empty);
9783                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9784
9785                if (!r.keeping) {
9786                    if (r.lastWakeTime != 0) {
9787                        long wtime;
9788                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9789                        synchronized (stats) {
9790                            wtime = stats.getProcessWakeTime(r.info.uid,
9791                                    r.pid, curRealtime);
9792                        }
9793                        long timeUsed = wtime - r.lastWakeTime;
9794                        pw.print(prefix);
9795                        pw.print("    ");
9796                        pw.print("keep awake over ");
9797                        TimeUtils.formatDuration(realtimeSince, pw);
9798                        pw.print(" used ");
9799                        TimeUtils.formatDuration(timeUsed, pw);
9800                        pw.print(" (");
9801                        pw.print((timeUsed*100)/realtimeSince);
9802                        pw.println("%)");
9803                    }
9804                    if (r.lastCpuTime != 0) {
9805                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9806                        pw.print(prefix);
9807                        pw.print("    ");
9808                        pw.print("run cpu over ");
9809                        TimeUtils.formatDuration(uptimeSince, pw);
9810                        pw.print(" used ");
9811                        TimeUtils.formatDuration(timeUsed, pw);
9812                        pw.print(" (");
9813                        pw.print((timeUsed*100)/uptimeSince);
9814                        pw.println("%)");
9815                    }
9816                }
9817            }
9818        }
9819        return true;
9820    }
9821
9822    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9823        ArrayList<ProcessRecord> procs;
9824        synchronized (this) {
9825            if (args != null && args.length > start
9826                    && args[start].charAt(0) != '-') {
9827                procs = new ArrayList<ProcessRecord>();
9828                int pid = -1;
9829                try {
9830                    pid = Integer.parseInt(args[start]);
9831                } catch (NumberFormatException e) {
9832
9833                }
9834                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9835                    ProcessRecord proc = mLruProcesses.get(i);
9836                    if (proc.pid == pid) {
9837                        procs.add(proc);
9838                    } else if (proc.processName.equals(args[start])) {
9839                        procs.add(proc);
9840                    }
9841                }
9842                if (procs.size() <= 0) {
9843                    pw.println("No process found for: " + args[start]);
9844                    return null;
9845                }
9846            } else {
9847                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9848            }
9849        }
9850        return procs;
9851    }
9852
9853    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9854            PrintWriter pw, String[] args) {
9855        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9856        if (procs == null) {
9857            return;
9858        }
9859
9860        long uptime = SystemClock.uptimeMillis();
9861        long realtime = SystemClock.elapsedRealtime();
9862        pw.println("Applications Graphics Acceleration Info:");
9863        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9864
9865        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9866            ProcessRecord r = procs.get(i);
9867            if (r.thread != null) {
9868                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9869                pw.flush();
9870                try {
9871                    TransferPipe tp = new TransferPipe();
9872                    try {
9873                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9874                        tp.go(fd);
9875                    } finally {
9876                        tp.kill();
9877                    }
9878                } catch (IOException e) {
9879                    pw.println("Failure while dumping the app: " + r);
9880                    pw.flush();
9881                } catch (RemoteException e) {
9882                    pw.println("Got a RemoteException while dumping the app " + r);
9883                    pw.flush();
9884                }
9885            }
9886        }
9887    }
9888
9889    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9890        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9891        if (procs == null) {
9892            return;
9893        }
9894
9895        pw.println("Applications Database Info:");
9896
9897        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9898            ProcessRecord r = procs.get(i);
9899            if (r.thread != null) {
9900                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9901                pw.flush();
9902                try {
9903                    TransferPipe tp = new TransferPipe();
9904                    try {
9905                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9906                        tp.go(fd);
9907                    } finally {
9908                        tp.kill();
9909                    }
9910                } catch (IOException e) {
9911                    pw.println("Failure while dumping the app: " + r);
9912                    pw.flush();
9913                } catch (RemoteException e) {
9914                    pw.println("Got a RemoteException while dumping the app " + r);
9915                    pw.flush();
9916                }
9917            }
9918        }
9919    }
9920
9921    final static class MemItem {
9922        final String label;
9923        final String shortLabel;
9924        final long pss;
9925        final int id;
9926        ArrayList<MemItem> subitems;
9927
9928        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9929            label = _label;
9930            shortLabel = _shortLabel;
9931            pss = _pss;
9932            id = _id;
9933        }
9934    }
9935
9936    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9937            boolean sort) {
9938        if (sort) {
9939            Collections.sort(items, new Comparator<MemItem>() {
9940                @Override
9941                public int compare(MemItem lhs, MemItem rhs) {
9942                    if (lhs.pss < rhs.pss) {
9943                        return 1;
9944                    } else if (lhs.pss > rhs.pss) {
9945                        return -1;
9946                    }
9947                    return 0;
9948                }
9949            });
9950        }
9951
9952        for (int i=0; i<items.size(); i++) {
9953            MemItem mi = items.get(i);
9954            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9955            if (mi.subitems != null) {
9956                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9957            }
9958        }
9959    }
9960
9961    // These are in KB.
9962    static final long[] DUMP_MEM_BUCKETS = new long[] {
9963        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9964        120*1024, 160*1024, 200*1024,
9965        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9966        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9967    };
9968
9969    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9970            boolean stackLike) {
9971        int start = label.lastIndexOf('.');
9972        if (start >= 0) start++;
9973        else start = 0;
9974        int end = label.length();
9975        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9976            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9977                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9978                out.append(bucket);
9979                out.append(stackLike ? "MB." : "MB ");
9980                out.append(label, start, end);
9981                return;
9982            }
9983        }
9984        out.append(memKB/1024);
9985        out.append(stackLike ? "MB." : "MB ");
9986        out.append(label, start, end);
9987    }
9988
9989    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9990            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9991            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9992            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9993            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9994    };
9995    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9996            "System", "Persistent", "Foreground",
9997            "Visible", "Perceptible", "Heavy Weight",
9998            "Backup", "A Services", "Home", "Previous",
9999            "B Services", "Background"
10000    };
10001
10002    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10003            PrintWriter pw, String prefix, String[] args, boolean brief,
10004            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10005        boolean dumpAll = false;
10006        boolean oomOnly = false;
10007
10008        int opti = 0;
10009        while (opti < args.length) {
10010            String opt = args[opti];
10011            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10012                break;
10013            }
10014            opti++;
10015            if ("-a".equals(opt)) {
10016                dumpAll = true;
10017            } else if ("--oom".equals(opt)) {
10018                oomOnly = true;
10019            } else if ("-h".equals(opt)) {
10020                pw.println("meminfo dump options: [-a] [--oom] [process]");
10021                pw.println("  -a: include all available information for each process.");
10022                pw.println("  --oom: only show processes organized by oom adj.");
10023                pw.println("If [process] is specified it can be the name or ");
10024                pw.println("pid of a specific process to dump.");
10025                return;
10026            } else {
10027                pw.println("Unknown argument: " + opt + "; use -h for help");
10028            }
10029        }
10030
10031        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10032        if (procs == null) {
10033            return;
10034        }
10035
10036        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10037        long uptime = SystemClock.uptimeMillis();
10038        long realtime = SystemClock.elapsedRealtime();
10039
10040        if (procs.size() == 1 || isCheckinRequest) {
10041            dumpAll = true;
10042        }
10043
10044        if (isCheckinRequest) {
10045            // short checkin version
10046            pw.println(uptime + "," + realtime);
10047            pw.flush();
10048        } else {
10049            pw.println("Applications Memory Usage (kB):");
10050            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10051        }
10052
10053        String[] innerArgs = new String[args.length-opti];
10054        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10055
10056        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10057        long nativePss=0, dalvikPss=0, otherPss=0;
10058        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10059
10060        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10061        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10062                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10063
10064        long totalPss = 0;
10065
10066        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10067            ProcessRecord r = procs.get(i);
10068            if (r.thread != null) {
10069                if (!isCheckinRequest && dumpAll) {
10070                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10071                    pw.flush();
10072                }
10073                Debug.MemoryInfo mi = null;
10074                if (dumpAll) {
10075                    try {
10076                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10077                    } catch (RemoteException e) {
10078                        if (!isCheckinRequest) {
10079                            pw.println("Got RemoteException!");
10080                            pw.flush();
10081                        }
10082                    }
10083                } else {
10084                    mi = new Debug.MemoryInfo();
10085                    Debug.getMemoryInfo(r.pid, mi);
10086                }
10087
10088                if (!isCheckinRequest && mi != null) {
10089                    long myTotalPss = mi.getTotalPss();
10090                    totalPss += myTotalPss;
10091                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10092                            r.processName, myTotalPss, 0);
10093                    procMems.add(pssItem);
10094
10095                    nativePss += mi.nativePss;
10096                    dalvikPss += mi.dalvikPss;
10097                    otherPss += mi.otherPss;
10098                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10099                        long mem = mi.getOtherPss(j);
10100                        miscPss[j] += mem;
10101                        otherPss -= mem;
10102                    }
10103
10104                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10105                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10106                                || oomIndex == (oomPss.length-1)) {
10107                            oomPss[oomIndex] += myTotalPss;
10108                            if (oomProcs[oomIndex] == null) {
10109                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10110                            }
10111                            oomProcs[oomIndex].add(pssItem);
10112                            break;
10113                        }
10114                    }
10115                }
10116            }
10117        }
10118
10119        if (!isCheckinRequest && procs.size() > 1) {
10120            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10121
10122            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10123            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10124            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10125            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10126                String label = Debug.MemoryInfo.getOtherLabel(j);
10127                catMems.add(new MemItem(label, label, miscPss[j], j));
10128            }
10129
10130            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10131            for (int j=0; j<oomPss.length; j++) {
10132                if (oomPss[j] != 0) {
10133                    String label = DUMP_MEM_OOM_LABEL[j];
10134                    MemItem item = new MemItem(label, label, oomPss[j],
10135                            DUMP_MEM_OOM_ADJ[j]);
10136                    item.subitems = oomProcs[j];
10137                    oomMems.add(item);
10138                }
10139            }
10140
10141            if (outTag != null || outStack != null) {
10142                if (outTag != null) {
10143                    appendMemBucket(outTag, totalPss, "total", false);
10144                }
10145                if (outStack != null) {
10146                    appendMemBucket(outStack, totalPss, "total", true);
10147                }
10148                boolean firstLine = true;
10149                for (int i=0; i<oomMems.size(); i++) {
10150                    MemItem miCat = oomMems.get(i);
10151                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10152                        continue;
10153                    }
10154                    if (miCat.id < ProcessList.SERVICE_ADJ
10155                            || miCat.id == ProcessList.HOME_APP_ADJ
10156                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10157                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10158                            outTag.append(" / ");
10159                        }
10160                        if (outStack != null) {
10161                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10162                                if (firstLine) {
10163                                    outStack.append(":");
10164                                    firstLine = false;
10165                                }
10166                                outStack.append("\n\t at ");
10167                            } else {
10168                                outStack.append("$");
10169                            }
10170                        }
10171                        for (int j=0; j<miCat.subitems.size(); j++) {
10172                            MemItem mi = miCat.subitems.get(j);
10173                            if (j > 0) {
10174                                if (outTag != null) {
10175                                    outTag.append(" ");
10176                                }
10177                                if (outStack != null) {
10178                                    outStack.append("$");
10179                                }
10180                            }
10181                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10182                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10183                            }
10184                            if (outStack != null) {
10185                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10186                            }
10187                        }
10188                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10189                            outStack.append("(");
10190                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10191                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10192                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10193                                    outStack.append(":");
10194                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10195                                }
10196                            }
10197                            outStack.append(")");
10198                        }
10199                    }
10200                }
10201            }
10202
10203            if (!brief && !oomOnly) {
10204                pw.println();
10205                pw.println("Total PSS by process:");
10206                dumpMemItems(pw, "  ", procMems, true);
10207                pw.println();
10208            }
10209            pw.println("Total PSS by OOM adjustment:");
10210            dumpMemItems(pw, "  ", oomMems, false);
10211            if (!oomOnly) {
10212                PrintWriter out = categoryPw != null ? categoryPw : pw;
10213                out.println();
10214                out.println("Total PSS by category:");
10215                dumpMemItems(out, "  ", catMems, true);
10216            }
10217            pw.println();
10218            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10219            final int[] SINGLE_LONG_FORMAT = new int[] {
10220                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10221            };
10222            long[] longOut = new long[1];
10223            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10224                    SINGLE_LONG_FORMAT, null, longOut, null);
10225            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10226            longOut[0] = 0;
10227            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10228                    SINGLE_LONG_FORMAT, null, longOut, null);
10229            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10230            longOut[0] = 0;
10231            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10232                    SINGLE_LONG_FORMAT, null, longOut, null);
10233            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10234            longOut[0] = 0;
10235            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10236                    SINGLE_LONG_FORMAT, null, longOut, null);
10237            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10238            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10239                    pw.print(shared); pw.println(" kB");
10240            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10241                    pw.print(voltile); pw.println(" kB volatile");
10242        }
10243    }
10244
10245    /**
10246     * Searches array of arguments for the specified string
10247     * @param args array of argument strings
10248     * @param value value to search for
10249     * @return true if the value is contained in the array
10250     */
10251    private static boolean scanArgs(String[] args, String value) {
10252        if (args != null) {
10253            for (String arg : args) {
10254                if (value.equals(arg)) {
10255                    return true;
10256                }
10257            }
10258        }
10259        return false;
10260    }
10261
10262    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10263            ContentProviderRecord cpr, boolean always) {
10264        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10265
10266        if (!inLaunching || always) {
10267            synchronized (cpr) {
10268                cpr.launchingApp = null;
10269                cpr.notifyAll();
10270            }
10271            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10272            String names[] = cpr.info.authority.split(";");
10273            for (int j = 0; j < names.length; j++) {
10274                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10275            }
10276        }
10277
10278        for (int i=0; i<cpr.connections.size(); i++) {
10279            ContentProviderConnection conn = cpr.connections.get(i);
10280            if (conn.waiting) {
10281                // If this connection is waiting for the provider, then we don't
10282                // need to mess with its process unless we are always removing
10283                // or for some reason the provider is not currently launching.
10284                if (inLaunching && !always) {
10285                    continue;
10286                }
10287            }
10288            ProcessRecord capp = conn.client;
10289            conn.dead = true;
10290            if (conn.stableCount > 0) {
10291                if (!capp.persistent && capp.thread != null
10292                        && capp.pid != 0
10293                        && capp.pid != MY_PID) {
10294                    Slog.i(TAG, "Kill " + capp.processName
10295                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10296                            + " in dying process " + (proc != null ? proc.processName : "??"));
10297                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10298                            capp.processName, capp.setAdj, "dying provider "
10299                                    + cpr.name.toShortString());
10300                    Process.killProcessQuiet(capp.pid);
10301                }
10302            } else if (capp.thread != null && conn.provider.provider != null) {
10303                try {
10304                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10305                } catch (RemoteException e) {
10306                }
10307                // In the protocol here, we don't expect the client to correctly
10308                // clean up this connection, we'll just remove it.
10309                cpr.connections.remove(i);
10310                conn.client.conProviders.remove(conn);
10311            }
10312        }
10313
10314        if (inLaunching && always) {
10315            mLaunchingProviders.remove(cpr);
10316        }
10317        return inLaunching;
10318    }
10319
10320    /**
10321     * Main code for cleaning up a process when it has gone away.  This is
10322     * called both as a result of the process dying, or directly when stopping
10323     * a process when running in single process mode.
10324     */
10325    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10326            boolean restarting, boolean allowRestart, int index) {
10327        if (index >= 0) {
10328            mLruProcesses.remove(index);
10329        }
10330
10331        mProcessesToGc.remove(app);
10332
10333        // Dismiss any open dialogs.
10334        if (app.crashDialog != null) {
10335            app.crashDialog.dismiss();
10336            app.crashDialog = null;
10337        }
10338        if (app.anrDialog != null) {
10339            app.anrDialog.dismiss();
10340            app.anrDialog = null;
10341        }
10342        if (app.waitDialog != null) {
10343            app.waitDialog.dismiss();
10344            app.waitDialog = null;
10345        }
10346
10347        app.crashing = false;
10348        app.notResponding = false;
10349
10350        app.resetPackageList();
10351        app.unlinkDeathRecipient();
10352        app.thread = null;
10353        app.forcingToForeground = null;
10354        app.foregroundServices = false;
10355        app.foregroundActivities = false;
10356        app.hasShownUi = false;
10357        app.hasAboveClient = false;
10358
10359        mServices.killServicesLocked(app, allowRestart);
10360
10361        boolean restart = false;
10362
10363        // Remove published content providers.
10364        if (!app.pubProviders.isEmpty()) {
10365            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10366            while (it.hasNext()) {
10367                ContentProviderRecord cpr = it.next();
10368
10369                final boolean always = app.bad || !allowRestart;
10370                if (removeDyingProviderLocked(app, cpr, always) || always) {
10371                    // We left the provider in the launching list, need to
10372                    // restart it.
10373                    restart = true;
10374                }
10375
10376                cpr.provider = null;
10377                cpr.proc = null;
10378            }
10379            app.pubProviders.clear();
10380        }
10381
10382        // Take care of any launching providers waiting for this process.
10383        if (checkAppInLaunchingProvidersLocked(app, false)) {
10384            restart = true;
10385        }
10386
10387        // Unregister from connected content providers.
10388        if (!app.conProviders.isEmpty()) {
10389            for (int i=0; i<app.conProviders.size(); i++) {
10390                ContentProviderConnection conn = app.conProviders.get(i);
10391                conn.provider.connections.remove(conn);
10392            }
10393            app.conProviders.clear();
10394        }
10395
10396        // At this point there may be remaining entries in mLaunchingProviders
10397        // where we were the only one waiting, so they are no longer of use.
10398        // Look for these and clean up if found.
10399        // XXX Commented out for now.  Trying to figure out a way to reproduce
10400        // the actual situation to identify what is actually going on.
10401        if (false) {
10402            for (int i=0; i<mLaunchingProviders.size(); i++) {
10403                ContentProviderRecord cpr = (ContentProviderRecord)
10404                        mLaunchingProviders.get(i);
10405                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10406                    synchronized (cpr) {
10407                        cpr.launchingApp = null;
10408                        cpr.notifyAll();
10409                    }
10410                }
10411            }
10412        }
10413
10414        skipCurrentReceiverLocked(app);
10415
10416        // Unregister any receivers.
10417        if (app.receivers.size() > 0) {
10418            Iterator<ReceiverList> it = app.receivers.iterator();
10419            while (it.hasNext()) {
10420                removeReceiverLocked(it.next());
10421            }
10422            app.receivers.clear();
10423        }
10424
10425        // If the app is undergoing backup, tell the backup manager about it
10426        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10427            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10428            try {
10429                IBackupManager bm = IBackupManager.Stub.asInterface(
10430                        ServiceManager.getService(Context.BACKUP_SERVICE));
10431                bm.agentDisconnected(app.info.packageName);
10432            } catch (RemoteException e) {
10433                // can't happen; backup manager is local
10434            }
10435        }
10436
10437        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10438            ProcessChangeItem item = mPendingProcessChanges.get(i);
10439            if (item.pid == app.pid) {
10440                mPendingProcessChanges.remove(i);
10441                mAvailProcessChanges.add(item);
10442            }
10443        }
10444        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10445
10446        // If the caller is restarting this app, then leave it in its
10447        // current lists and let the caller take care of it.
10448        if (restarting) {
10449            return;
10450        }
10451
10452        if (!app.persistent || app.isolated) {
10453            if (DEBUG_PROCESSES) Slog.v(TAG,
10454                    "Removing non-persistent process during cleanup: " + app);
10455            mProcessNames.remove(app.processName, app.uid);
10456            mIsolatedProcesses.remove(app.uid);
10457            if (mHeavyWeightProcess == app) {
10458                mHeavyWeightProcess = null;
10459                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10460            }
10461        } else if (!app.removed) {
10462            // This app is persistent, so we need to keep its record around.
10463            // If it is not already on the pending app list, add it there
10464            // and start a new process for it.
10465            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10466                mPersistentStartingProcesses.add(app);
10467                restart = true;
10468            }
10469        }
10470        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10471                "Clean-up removing on hold: " + app);
10472        mProcessesOnHold.remove(app);
10473
10474        if (app == mHomeProcess) {
10475            mHomeProcess = null;
10476        }
10477        if (app == mPreviousProcess) {
10478            mPreviousProcess = null;
10479        }
10480
10481        if (restart && !app.isolated) {
10482            // We have components that still need to be running in the
10483            // process, so re-launch it.
10484            mProcessNames.put(app.processName, app.uid, app);
10485            startProcessLocked(app, "restart", app.processName);
10486        } else if (app.pid > 0 && app.pid != MY_PID) {
10487            // Goodbye!
10488            synchronized (mPidsSelfLocked) {
10489                mPidsSelfLocked.remove(app.pid);
10490                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10491            }
10492            app.setPid(0);
10493        }
10494    }
10495
10496    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10497        // Look through the content providers we are waiting to have launched,
10498        // and if any run in this process then either schedule a restart of
10499        // the process or kill the client waiting for it if this process has
10500        // gone bad.
10501        int NL = mLaunchingProviders.size();
10502        boolean restart = false;
10503        for (int i=0; i<NL; i++) {
10504            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10505            if (cpr.launchingApp == app) {
10506                if (!alwaysBad && !app.bad) {
10507                    restart = true;
10508                } else {
10509                    removeDyingProviderLocked(app, cpr, true);
10510                    NL = mLaunchingProviders.size();
10511                }
10512            }
10513        }
10514        return restart;
10515    }
10516
10517    // =========================================================
10518    // SERVICES
10519    // =========================================================
10520
10521    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10522            int flags) {
10523        enforceNotIsolatedCaller("getServices");
10524        synchronized (this) {
10525            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10526        }
10527    }
10528
10529    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10530        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10531        synchronized (this) {
10532            return mServices.getRunningServiceControlPanelLocked(name);
10533        }
10534    }
10535
10536    public ComponentName startService(IApplicationThread caller, Intent service,
10537            String resolvedType) {
10538        enforceNotIsolatedCaller("startService");
10539        // Refuse possible leaked file descriptors
10540        if (service != null && service.hasFileDescriptors() == true) {
10541            throw new IllegalArgumentException("File descriptors passed in Intent");
10542        }
10543
10544        if (DEBUG_SERVICE)
10545            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10546        synchronized(this) {
10547            final int callingPid = Binder.getCallingPid();
10548            final int callingUid = Binder.getCallingUid();
10549            final long origId = Binder.clearCallingIdentity();
10550            ComponentName res = mServices.startServiceLocked(caller, service,
10551                    resolvedType, callingPid, callingUid);
10552            Binder.restoreCallingIdentity(origId);
10553            return res;
10554        }
10555    }
10556
10557    ComponentName startServiceInPackage(int uid,
10558            Intent service, String resolvedType) {
10559        synchronized(this) {
10560            if (DEBUG_SERVICE)
10561                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10562            final long origId = Binder.clearCallingIdentity();
10563            ComponentName res = mServices.startServiceLocked(null, service,
10564                    resolvedType, -1, uid);
10565            Binder.restoreCallingIdentity(origId);
10566            return res;
10567        }
10568    }
10569
10570    public int stopService(IApplicationThread caller, Intent service,
10571            String resolvedType) {
10572        enforceNotIsolatedCaller("stopService");
10573        // Refuse possible leaked file descriptors
10574        if (service != null && service.hasFileDescriptors() == true) {
10575            throw new IllegalArgumentException("File descriptors passed in Intent");
10576        }
10577
10578        synchronized(this) {
10579            return mServices.stopServiceLocked(caller, service, resolvedType);
10580        }
10581    }
10582
10583    public IBinder peekService(Intent service, String resolvedType) {
10584        enforceNotIsolatedCaller("peekService");
10585        // Refuse possible leaked file descriptors
10586        if (service != null && service.hasFileDescriptors() == true) {
10587            throw new IllegalArgumentException("File descriptors passed in Intent");
10588        }
10589        synchronized(this) {
10590            return mServices.peekServiceLocked(service, resolvedType);
10591        }
10592    }
10593
10594    public boolean stopServiceToken(ComponentName className, IBinder token,
10595            int startId) {
10596        synchronized(this) {
10597            return mServices.stopServiceTokenLocked(className, token, startId);
10598        }
10599    }
10600
10601    public void setServiceForeground(ComponentName className, IBinder token,
10602            int id, Notification notification, boolean removeNotification) {
10603        synchronized(this) {
10604            mServices.setServiceForegroundLocked(className, token, id, notification,
10605                    removeNotification);
10606        }
10607    }
10608
10609    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10610            String className, int flags) {
10611        boolean result = false;
10612        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10613            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10614                if (ActivityManager.checkUidPermission(
10615                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10616                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10617                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10618                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10619                            + " requests FLAG_SINGLE_USER, but app does not hold "
10620                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10621                    Slog.w(TAG, msg);
10622                    throw new SecurityException(msg);
10623                }
10624                result = true;
10625            }
10626        } else if (componentProcessName == aInfo.packageName) {
10627            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10628        } else if ("system".equals(componentProcessName)) {
10629            result = true;
10630        }
10631        if (DEBUG_MU) {
10632            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10633                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10634        }
10635        return result;
10636    }
10637
10638    public int bindService(IApplicationThread caller, IBinder token,
10639            Intent service, String resolvedType,
10640            IServiceConnection connection, int flags, int userId) {
10641        enforceNotIsolatedCaller("bindService");
10642        // Refuse possible leaked file descriptors
10643        if (service != null && service.hasFileDescriptors() == true) {
10644            throw new IllegalArgumentException("File descriptors passed in Intent");
10645        }
10646
10647        checkValidCaller(Binder.getCallingUid(), userId);
10648
10649        synchronized(this) {
10650            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10651                    connection, flags, userId);
10652        }
10653    }
10654
10655    public boolean unbindService(IServiceConnection connection) {
10656        synchronized (this) {
10657            return mServices.unbindServiceLocked(connection);
10658        }
10659    }
10660
10661    public void publishService(IBinder token, Intent intent, IBinder service) {
10662        // Refuse possible leaked file descriptors
10663        if (intent != null && intent.hasFileDescriptors() == true) {
10664            throw new IllegalArgumentException("File descriptors passed in Intent");
10665        }
10666
10667        synchronized(this) {
10668            if (!(token instanceof ServiceRecord)) {
10669                throw new IllegalArgumentException("Invalid service token");
10670            }
10671            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10672        }
10673    }
10674
10675    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10676        // Refuse possible leaked file descriptors
10677        if (intent != null && intent.hasFileDescriptors() == true) {
10678            throw new IllegalArgumentException("File descriptors passed in Intent");
10679        }
10680
10681        synchronized(this) {
10682            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10683        }
10684    }
10685
10686    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10687        synchronized(this) {
10688            if (!(token instanceof ServiceRecord)) {
10689                throw new IllegalArgumentException("Invalid service token");
10690            }
10691            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10692        }
10693    }
10694
10695    // =========================================================
10696    // BACKUP AND RESTORE
10697    // =========================================================
10698
10699    // Cause the target app to be launched if necessary and its backup agent
10700    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10701    // activity manager to announce its creation.
10702    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10703        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10704        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10705
10706        synchronized(this) {
10707            // !!! TODO: currently no check here that we're already bound
10708            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10709            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10710            synchronized (stats) {
10711                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10712            }
10713
10714            // Backup agent is now in use, its package can't be stopped.
10715            try {
10716                AppGlobals.getPackageManager().setPackageStoppedState(
10717                        app.packageName, false, UserHandle.getUserId(app.uid));
10718            } catch (RemoteException e) {
10719            } catch (IllegalArgumentException e) {
10720                Slog.w(TAG, "Failed trying to unstop package "
10721                        + app.packageName + ": " + e);
10722            }
10723
10724            BackupRecord r = new BackupRecord(ss, app, backupMode);
10725            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10726                    ? new ComponentName(app.packageName, app.backupAgentName)
10727                    : new ComponentName("android", "FullBackupAgent");
10728            // startProcessLocked() returns existing proc's record if it's already running
10729            ProcessRecord proc = startProcessLocked(app.processName, app,
10730                    false, 0, "backup", hostingName, false, false);
10731            if (proc == null) {
10732                Slog.e(TAG, "Unable to start backup agent process " + r);
10733                return false;
10734            }
10735
10736            r.app = proc;
10737            mBackupTarget = r;
10738            mBackupAppName = app.packageName;
10739
10740            // Try not to kill the process during backup
10741            updateOomAdjLocked(proc);
10742
10743            // If the process is already attached, schedule the creation of the backup agent now.
10744            // If it is not yet live, this will be done when it attaches to the framework.
10745            if (proc.thread != null) {
10746                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10747                try {
10748                    proc.thread.scheduleCreateBackupAgent(app,
10749                            compatibilityInfoForPackageLocked(app), backupMode);
10750                } catch (RemoteException e) {
10751                    // Will time out on the backup manager side
10752                }
10753            } else {
10754                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10755            }
10756            // Invariants: at this point, the target app process exists and the application
10757            // is either already running or in the process of coming up.  mBackupTarget and
10758            // mBackupAppName describe the app, so that when it binds back to the AM we
10759            // know that it's scheduled for a backup-agent operation.
10760        }
10761
10762        return true;
10763    }
10764
10765    // A backup agent has just come up
10766    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10767        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10768                + " = " + agent);
10769
10770        synchronized(this) {
10771            if (!agentPackageName.equals(mBackupAppName)) {
10772                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10773                return;
10774            }
10775        }
10776
10777        long oldIdent = Binder.clearCallingIdentity();
10778        try {
10779            IBackupManager bm = IBackupManager.Stub.asInterface(
10780                    ServiceManager.getService(Context.BACKUP_SERVICE));
10781            bm.agentConnected(agentPackageName, agent);
10782        } catch (RemoteException e) {
10783            // can't happen; the backup manager service is local
10784        } catch (Exception e) {
10785            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10786            e.printStackTrace();
10787        } finally {
10788            Binder.restoreCallingIdentity(oldIdent);
10789        }
10790    }
10791
10792    // done with this agent
10793    public void unbindBackupAgent(ApplicationInfo appInfo) {
10794        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10795        if (appInfo == null) {
10796            Slog.w(TAG, "unbind backup agent for null app");
10797            return;
10798        }
10799
10800        synchronized(this) {
10801            if (mBackupAppName == null) {
10802                Slog.w(TAG, "Unbinding backup agent with no active backup");
10803                return;
10804            }
10805
10806            if (!mBackupAppName.equals(appInfo.packageName)) {
10807                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10808                return;
10809            }
10810
10811            ProcessRecord proc = mBackupTarget.app;
10812            mBackupTarget = null;
10813            mBackupAppName = null;
10814
10815            // Not backing this app up any more; reset its OOM adjustment
10816            updateOomAdjLocked(proc);
10817
10818            // If the app crashed during backup, 'thread' will be null here
10819            if (proc.thread != null) {
10820                try {
10821                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10822                            compatibilityInfoForPackageLocked(appInfo));
10823                } catch (Exception e) {
10824                    Slog.e(TAG, "Exception when unbinding backup agent:");
10825                    e.printStackTrace();
10826                }
10827            }
10828        }
10829    }
10830    // =========================================================
10831    // BROADCASTS
10832    // =========================================================
10833
10834    private final List getStickiesLocked(String action, IntentFilter filter,
10835            List cur) {
10836        final ContentResolver resolver = mContext.getContentResolver();
10837        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10838        if (list == null) {
10839            return cur;
10840        }
10841        int N = list.size();
10842        for (int i=0; i<N; i++) {
10843            Intent intent = list.get(i);
10844            if (filter.match(resolver, intent, true, TAG) >= 0) {
10845                if (cur == null) {
10846                    cur = new ArrayList<Intent>();
10847                }
10848                cur.add(intent);
10849            }
10850        }
10851        return cur;
10852    }
10853
10854    boolean isPendingBroadcastProcessLocked(int pid) {
10855        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10856                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10857    }
10858
10859    void skipPendingBroadcastLocked(int pid) {
10860            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10861            for (BroadcastQueue queue : mBroadcastQueues) {
10862                queue.skipPendingBroadcastLocked(pid);
10863            }
10864    }
10865
10866    // The app just attached; send any pending broadcasts that it should receive
10867    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10868        boolean didSomething = false;
10869        for (BroadcastQueue queue : mBroadcastQueues) {
10870            didSomething |= queue.sendPendingBroadcastsLocked(app);
10871        }
10872        return didSomething;
10873    }
10874
10875    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10876            IIntentReceiver receiver, IntentFilter filter, String permission) {
10877        enforceNotIsolatedCaller("registerReceiver");
10878        int callingUid;
10879        synchronized(this) {
10880            ProcessRecord callerApp = null;
10881            if (caller != null) {
10882                callerApp = getRecordForAppLocked(caller);
10883                if (callerApp == null) {
10884                    throw new SecurityException(
10885                            "Unable to find app for caller " + caller
10886                            + " (pid=" + Binder.getCallingPid()
10887                            + ") when registering receiver " + receiver);
10888                }
10889                if (callerApp.info.uid != Process.SYSTEM_UID &&
10890                        !callerApp.pkgList.contains(callerPackage)) {
10891                    throw new SecurityException("Given caller package " + callerPackage
10892                            + " is not running in process " + callerApp);
10893                }
10894                callingUid = callerApp.info.uid;
10895            } else {
10896                callerPackage = null;
10897                callingUid = Binder.getCallingUid();
10898            }
10899
10900            List allSticky = null;
10901
10902            // Look for any matching sticky broadcasts...
10903            Iterator actions = filter.actionsIterator();
10904            if (actions != null) {
10905                while (actions.hasNext()) {
10906                    String action = (String)actions.next();
10907                    allSticky = getStickiesLocked(action, filter, allSticky);
10908                }
10909            } else {
10910                allSticky = getStickiesLocked(null, filter, allSticky);
10911            }
10912
10913            // The first sticky in the list is returned directly back to
10914            // the client.
10915            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10916
10917            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10918                    + ": " + sticky);
10919
10920            if (receiver == null) {
10921                return sticky;
10922            }
10923
10924            ReceiverList rl
10925                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10926            if (rl == null) {
10927                rl = new ReceiverList(this, callerApp,
10928                        Binder.getCallingPid(),
10929                        Binder.getCallingUid(), receiver);
10930                if (rl.app != null) {
10931                    rl.app.receivers.add(rl);
10932                } else {
10933                    try {
10934                        receiver.asBinder().linkToDeath(rl, 0);
10935                    } catch (RemoteException e) {
10936                        return sticky;
10937                    }
10938                    rl.linkedToDeath = true;
10939                }
10940                mRegisteredReceivers.put(receiver.asBinder(), rl);
10941            }
10942            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10943                    permission, callingUid);
10944            rl.add(bf);
10945            if (!bf.debugCheck()) {
10946                Slog.w(TAG, "==> For Dynamic broadast");
10947            }
10948            mReceiverResolver.addFilter(bf);
10949
10950            // Enqueue broadcasts for all existing stickies that match
10951            // this filter.
10952            if (allSticky != null) {
10953                ArrayList receivers = new ArrayList();
10954                receivers.add(bf);
10955
10956                int N = allSticky.size();
10957                for (int i=0; i<N; i++) {
10958                    Intent intent = (Intent)allSticky.get(i);
10959                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10960                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10961                            null, -1, -1, null, receivers, null, 0, null, null,
10962                            false, true, true, false);
10963                    queue.enqueueParallelBroadcastLocked(r);
10964                    queue.scheduleBroadcastsLocked();
10965                }
10966            }
10967
10968            return sticky;
10969        }
10970    }
10971
10972    public void unregisterReceiver(IIntentReceiver receiver) {
10973        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10974
10975        final long origId = Binder.clearCallingIdentity();
10976        try {
10977            boolean doTrim = false;
10978
10979            synchronized(this) {
10980                ReceiverList rl
10981                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10982                if (rl != null) {
10983                    if (rl.curBroadcast != null) {
10984                        BroadcastRecord r = rl.curBroadcast;
10985                        final boolean doNext = finishReceiverLocked(
10986                                receiver.asBinder(), r.resultCode, r.resultData,
10987                                r.resultExtras, r.resultAbort, true);
10988                        if (doNext) {
10989                            doTrim = true;
10990                            r.queue.processNextBroadcast(false);
10991                        }
10992                    }
10993
10994                    if (rl.app != null) {
10995                        rl.app.receivers.remove(rl);
10996                    }
10997                    removeReceiverLocked(rl);
10998                    if (rl.linkedToDeath) {
10999                        rl.linkedToDeath = false;
11000                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11001                    }
11002                }
11003            }
11004
11005            // If we actually concluded any broadcasts, we might now be able
11006            // to trim the recipients' apps from our working set
11007            if (doTrim) {
11008                trimApplications();
11009                return;
11010            }
11011
11012        } finally {
11013            Binder.restoreCallingIdentity(origId);
11014        }
11015    }
11016
11017    void removeReceiverLocked(ReceiverList rl) {
11018        mRegisteredReceivers.remove(rl.receiver.asBinder());
11019        int N = rl.size();
11020        for (int i=0; i<N; i++) {
11021            mReceiverResolver.removeFilter(rl.get(i));
11022        }
11023    }
11024
11025    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11026        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11027            ProcessRecord r = mLruProcesses.get(i);
11028            if (r.thread != null) {
11029                try {
11030                    r.thread.dispatchPackageBroadcast(cmd, packages);
11031                } catch (RemoteException ex) {
11032                }
11033            }
11034        }
11035    }
11036
11037    private final int broadcastIntentLocked(ProcessRecord callerApp,
11038            String callerPackage, Intent intent, String resolvedType,
11039            IIntentReceiver resultTo, int resultCode, String resultData,
11040            Bundle map, String requiredPermission,
11041            boolean ordered, boolean sticky, int callingPid, int callingUid,
11042            int userId) {
11043        intent = new Intent(intent);
11044
11045        // By default broadcasts do not go to stopped apps.
11046        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11047
11048        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11049            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11050            + " ordered=" + ordered + " userid=" + userId);
11051        if ((resultTo != null) && !ordered) {
11052            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11053        }
11054
11055        boolean onlySendToCaller = false;
11056
11057        // If the caller is trying to send this broadcast to a different
11058        // user, verify that is allowed.
11059        if (UserHandle.getUserId(callingUid) != userId) {
11060            if (checkComponentPermission(
11061                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11062                    callingPid, callingUid, -1, true)
11063                    != PackageManager.PERMISSION_GRANTED) {
11064                if (checkComponentPermission(
11065                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11066                        callingPid, callingUid, -1, true)
11067                        == PackageManager.PERMISSION_GRANTED) {
11068                    onlySendToCaller = true;
11069                } else {
11070                    String msg = "Permission Denial: " + intent.getAction()
11071                            + " broadcast from " + callerPackage
11072                            + " asks to send as user " + userId
11073                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11074                            + "; this requires "
11075                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11076                    Slog.w(TAG, msg);
11077                    throw new SecurityException(msg);
11078                }
11079            }
11080        }
11081
11082        // Handle special intents: if this broadcast is from the package
11083        // manager about a package being removed, we need to remove all of
11084        // its activities from the history stack.
11085        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11086                intent.getAction());
11087        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11088                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11089                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11090                || uidRemoved) {
11091            if (checkComponentPermission(
11092                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11093                    callingPid, callingUid, -1, true)
11094                    == PackageManager.PERMISSION_GRANTED) {
11095                if (uidRemoved) {
11096                    final Bundle intentExtras = intent.getExtras();
11097                    final int uid = intentExtras != null
11098                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11099                    if (uid >= 0) {
11100                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11101                        synchronized (bs) {
11102                            bs.removeUidStatsLocked(uid);
11103                        }
11104                    }
11105                } else {
11106                    // If resources are unvailble just force stop all
11107                    // those packages and flush the attribute cache as well.
11108                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11109                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11110                        if (list != null && (list.length > 0)) {
11111                            for (String pkg : list) {
11112                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11113                            }
11114                            sendPackageBroadcastLocked(
11115                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11116                        }
11117                    } else {
11118                        Uri data = intent.getData();
11119                        String ssp;
11120                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11121                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11122                                forceStopPackageLocked(ssp,
11123                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11124                                        false, userId);
11125                            }
11126                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11127                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11128                                        new String[] {ssp});
11129                            }
11130                        }
11131                    }
11132                }
11133            } else {
11134                String msg = "Permission Denial: " + intent.getAction()
11135                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11136                        + ", uid=" + callingUid + ")"
11137                        + " requires "
11138                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11139                Slog.w(TAG, msg);
11140                throw new SecurityException(msg);
11141            }
11142
11143        // Special case for adding a package: by default turn on compatibility
11144        // mode.
11145        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11146            Uri data = intent.getData();
11147            String ssp;
11148            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11149                mCompatModePackages.handlePackageAddedLocked(ssp,
11150                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11151            }
11152        }
11153
11154        /*
11155         * If this is the time zone changed action, queue up a message that will reset the timezone
11156         * of all currently running processes. This message will get queued up before the broadcast
11157         * happens.
11158         */
11159        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11160            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11161        }
11162
11163        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11164            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11165        }
11166
11167        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11168            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11169            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11170        }
11171
11172        /*
11173         * Prevent non-system code (defined here to be non-persistent
11174         * processes) from sending protected broadcasts.
11175         */
11176        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11177            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11178            callingUid == 0) {
11179            // Always okay.
11180        } else if (callerApp == null || !callerApp.persistent) {
11181            try {
11182                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11183                        intent.getAction())) {
11184                    String msg = "Permission Denial: not allowed to send broadcast "
11185                            + intent.getAction() + " from pid="
11186                            + callingPid + ", uid=" + callingUid;
11187                    Slog.w(TAG, msg);
11188                    throw new SecurityException(msg);
11189                }
11190            } catch (RemoteException e) {
11191                Slog.w(TAG, "Remote exception", e);
11192                return ActivityManager.BROADCAST_SUCCESS;
11193            }
11194        }
11195
11196        // Add to the sticky list if requested.
11197        if (sticky) {
11198            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11199                    callingPid, callingUid)
11200                    != PackageManager.PERMISSION_GRANTED) {
11201                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11202                        + callingPid + ", uid=" + callingUid
11203                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11204                Slog.w(TAG, msg);
11205                throw new SecurityException(msg);
11206            }
11207            if (requiredPermission != null) {
11208                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11209                        + " and enforce permission " + requiredPermission);
11210                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11211            }
11212            if (intent.getComponent() != null) {
11213                throw new SecurityException(
11214                        "Sticky broadcasts can't target a specific component");
11215            }
11216            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11217            if (list == null) {
11218                list = new ArrayList<Intent>();
11219                mStickyBroadcasts.put(intent.getAction(), list);
11220            }
11221            int N = list.size();
11222            int i;
11223            for (i=0; i<N; i++) {
11224                if (intent.filterEquals(list.get(i))) {
11225                    // This sticky already exists, replace it.
11226                    list.set(i, new Intent(intent));
11227                    break;
11228                }
11229            }
11230            if (i >= N) {
11231                list.add(new Intent(intent));
11232            }
11233        }
11234
11235        // Figure out who all will receive this broadcast.
11236        List receivers = null;
11237        List<BroadcastFilter> registeredReceivers = null;
11238        try {
11239            // Need to resolve the intent to interested receivers...
11240            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11241                     == 0) {
11242                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11243                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11244            }
11245            if (intent.getComponent() == null) {
11246                registeredReceivers = mReceiverResolver.queryIntent(intent,
11247                        resolvedType, false, userId);
11248            }
11249        } catch (RemoteException ex) {
11250            // pm is in same process, this will never happen.
11251        }
11252
11253        final boolean replacePending =
11254                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11255
11256        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11257                + " replacePending=" + replacePending);
11258
11259        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11260        if (!ordered && NR > 0) {
11261            // If we are not serializing this broadcast, then send the
11262            // registered receivers separately so they don't wait for the
11263            // components to be launched.
11264            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11265            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11266                    callerPackage, callingPid, callingUid, requiredPermission,
11267                    registeredReceivers, resultTo, resultCode, resultData, map,
11268                    ordered, sticky, false, onlySendToCaller);
11269            if (DEBUG_BROADCAST) Slog.v(
11270                    TAG, "Enqueueing parallel broadcast " + r);
11271            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11272            if (!replaced) {
11273                queue.enqueueParallelBroadcastLocked(r);
11274                queue.scheduleBroadcastsLocked();
11275            }
11276            registeredReceivers = null;
11277            NR = 0;
11278        }
11279
11280        // Merge into one list.
11281        int ir = 0;
11282        if (receivers != null) {
11283            // A special case for PACKAGE_ADDED: do not allow the package
11284            // being added to see this broadcast.  This prevents them from
11285            // using this as a back door to get run as soon as they are
11286            // installed.  Maybe in the future we want to have a special install
11287            // broadcast or such for apps, but we'd like to deliberately make
11288            // this decision.
11289            String skipPackages[] = null;
11290            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11291                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11292                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11293                Uri data = intent.getData();
11294                if (data != null) {
11295                    String pkgName = data.getSchemeSpecificPart();
11296                    if (pkgName != null) {
11297                        skipPackages = new String[] { pkgName };
11298                    }
11299                }
11300            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11301                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11302            }
11303            if (skipPackages != null && (skipPackages.length > 0)) {
11304                for (String skipPackage : skipPackages) {
11305                    if (skipPackage != null) {
11306                        int NT = receivers.size();
11307                        for (int it=0; it<NT; it++) {
11308                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11309                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11310                                receivers.remove(it);
11311                                it--;
11312                                NT--;
11313                            }
11314                        }
11315                    }
11316                }
11317            }
11318
11319            int NT = receivers != null ? receivers.size() : 0;
11320            int it = 0;
11321            ResolveInfo curt = null;
11322            BroadcastFilter curr = null;
11323            while (it < NT && ir < NR) {
11324                if (curt == null) {
11325                    curt = (ResolveInfo)receivers.get(it);
11326                }
11327                if (curr == null) {
11328                    curr = registeredReceivers.get(ir);
11329                }
11330                if (curr.getPriority() >= curt.priority) {
11331                    // Insert this broadcast record into the final list.
11332                    receivers.add(it, curr);
11333                    ir++;
11334                    curr = null;
11335                    it++;
11336                    NT++;
11337                } else {
11338                    // Skip to the next ResolveInfo in the final list.
11339                    it++;
11340                    curt = null;
11341                }
11342            }
11343        }
11344        while (ir < NR) {
11345            if (receivers == null) {
11346                receivers = new ArrayList();
11347            }
11348            receivers.add(registeredReceivers.get(ir));
11349            ir++;
11350        }
11351
11352        if ((receivers != null && receivers.size() > 0)
11353                || resultTo != null) {
11354            BroadcastQueue queue = broadcastQueueForIntent(intent);
11355            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11356                    callerPackage, callingPid, callingUid, requiredPermission,
11357                    receivers, resultTo, resultCode, resultData, map, ordered,
11358                    sticky, false, onlySendToCaller);
11359            if (DEBUG_BROADCAST) Slog.v(
11360                    TAG, "Enqueueing ordered broadcast " + r
11361                    + ": prev had " + queue.mOrderedBroadcasts.size());
11362            if (DEBUG_BROADCAST) {
11363                int seq = r.intent.getIntExtra("seq", -1);
11364                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11365            }
11366            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11367            if (!replaced) {
11368                queue.enqueueOrderedBroadcastLocked(r);
11369                queue.scheduleBroadcastsLocked();
11370            }
11371        }
11372
11373        return ActivityManager.BROADCAST_SUCCESS;
11374    }
11375
11376    final Intent verifyBroadcastLocked(Intent intent) {
11377        // Refuse possible leaked file descriptors
11378        if (intent != null && intent.hasFileDescriptors() == true) {
11379            throw new IllegalArgumentException("File descriptors passed in Intent");
11380        }
11381
11382        int flags = intent.getFlags();
11383
11384        if (!mProcessesReady) {
11385            // if the caller really truly claims to know what they're doing, go
11386            // ahead and allow the broadcast without launching any receivers
11387            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11388                intent = new Intent(intent);
11389                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11390            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11391                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11392                        + " before boot completion");
11393                throw new IllegalStateException("Cannot broadcast before boot completed");
11394            }
11395        }
11396
11397        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11398            throw new IllegalArgumentException(
11399                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11400        }
11401
11402        return intent;
11403    }
11404
11405    public final int broadcastIntent(IApplicationThread caller,
11406            Intent intent, String resolvedType, IIntentReceiver resultTo,
11407            int resultCode, String resultData, Bundle map,
11408            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11409        enforceNotIsolatedCaller("broadcastIntent");
11410        synchronized(this) {
11411            intent = verifyBroadcastLocked(intent);
11412
11413            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11414            final int callingPid = Binder.getCallingPid();
11415            final int callingUid = Binder.getCallingUid();
11416            final long origId = Binder.clearCallingIdentity();
11417            int res = broadcastIntentLocked(callerApp,
11418                    callerApp != null ? callerApp.info.packageName : null,
11419                    intent, resolvedType, resultTo,
11420                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11421                    callingPid, callingUid, userId);
11422            Binder.restoreCallingIdentity(origId);
11423            return res;
11424        }
11425    }
11426
11427    int broadcastIntentInPackage(String packageName, int uid,
11428            Intent intent, String resolvedType, IIntentReceiver resultTo,
11429            int resultCode, String resultData, Bundle map,
11430            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11431        synchronized(this) {
11432            intent = verifyBroadcastLocked(intent);
11433
11434            final long origId = Binder.clearCallingIdentity();
11435            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11436                    resultTo, resultCode, resultData, map, requiredPermission,
11437                    serialized, sticky, -1, uid, userId);
11438            Binder.restoreCallingIdentity(origId);
11439            return res;
11440        }
11441    }
11442
11443    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11444    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11445        // Refuse possible leaked file descriptors
11446        if (intent != null && intent.hasFileDescriptors() == true) {
11447            throw new IllegalArgumentException("File descriptors passed in Intent");
11448        }
11449
11450        synchronized(this) {
11451            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11452                    != PackageManager.PERMISSION_GRANTED) {
11453                String msg = "Permission Denial: unbroadcastIntent() from pid="
11454                        + Binder.getCallingPid()
11455                        + ", uid=" + Binder.getCallingUid()
11456                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11457                Slog.w(TAG, msg);
11458                throw new SecurityException(msg);
11459            }
11460            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11461            if (list != null) {
11462                int N = list.size();
11463                int i;
11464                for (i=0; i<N; i++) {
11465                    if (intent.filterEquals(list.get(i))) {
11466                        list.remove(i);
11467                        break;
11468                    }
11469                }
11470            }
11471        }
11472    }
11473
11474    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11475            String resultData, Bundle resultExtras, boolean resultAbort,
11476            boolean explicit) {
11477        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11478        if (r == null) {
11479            Slog.w(TAG, "finishReceiver called but not found on queue");
11480            return false;
11481        }
11482
11483        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11484                explicit);
11485    }
11486
11487    public void finishReceiver(IBinder who, int resultCode, String resultData,
11488            Bundle resultExtras, boolean resultAbort) {
11489        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11490
11491        // Refuse possible leaked file descriptors
11492        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11493            throw new IllegalArgumentException("File descriptors passed in Bundle");
11494        }
11495
11496        final long origId = Binder.clearCallingIdentity();
11497        try {
11498            boolean doNext = false;
11499            BroadcastRecord r = null;
11500
11501            synchronized(this) {
11502                r = broadcastRecordForReceiverLocked(who);
11503                if (r != null) {
11504                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11505                        resultData, resultExtras, resultAbort, true);
11506                }
11507            }
11508
11509            if (doNext) {
11510                r.queue.processNextBroadcast(false);
11511            }
11512            trimApplications();
11513        } finally {
11514            Binder.restoreCallingIdentity(origId);
11515        }
11516    }
11517
11518    // =========================================================
11519    // INSTRUMENTATION
11520    // =========================================================
11521
11522    public boolean startInstrumentation(ComponentName className,
11523            String profileFile, int flags, Bundle arguments,
11524            IInstrumentationWatcher watcher) {
11525        enforceNotIsolatedCaller("startInstrumentation");
11526        // Refuse possible leaked file descriptors
11527        if (arguments != null && arguments.hasFileDescriptors()) {
11528            throw new IllegalArgumentException("File descriptors passed in Bundle");
11529        }
11530
11531        synchronized(this) {
11532            InstrumentationInfo ii = null;
11533            ApplicationInfo ai = null;
11534            try {
11535                ii = mContext.getPackageManager().getInstrumentationInfo(
11536                    className, STOCK_PM_FLAGS);
11537                ai = mContext.getPackageManager().getApplicationInfo(
11538                        ii.targetPackage, STOCK_PM_FLAGS);
11539            } catch (PackageManager.NameNotFoundException e) {
11540            }
11541            if (ii == null) {
11542                reportStartInstrumentationFailure(watcher, className,
11543                        "Unable to find instrumentation info for: " + className);
11544                return false;
11545            }
11546            if (ai == null) {
11547                reportStartInstrumentationFailure(watcher, className,
11548                        "Unable to find instrumentation target package: " + ii.targetPackage);
11549                return false;
11550            }
11551
11552            int match = mContext.getPackageManager().checkSignatures(
11553                    ii.targetPackage, ii.packageName);
11554            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11555                String msg = "Permission Denial: starting instrumentation "
11556                        + className + " from pid="
11557                        + Binder.getCallingPid()
11558                        + ", uid=" + Binder.getCallingPid()
11559                        + " not allowed because package " + ii.packageName
11560                        + " does not have a signature matching the target "
11561                        + ii.targetPackage;
11562                reportStartInstrumentationFailure(watcher, className, msg);
11563                throw new SecurityException(msg);
11564            }
11565
11566            int userId = UserHandle.getCallingUserId();
11567            final long origId = Binder.clearCallingIdentity();
11568            // Instrumentation can kill and relaunch even persistent processes
11569            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11570            ProcessRecord app = addAppLocked(ai, false);
11571            app.instrumentationClass = className;
11572            app.instrumentationInfo = ai;
11573            app.instrumentationProfileFile = profileFile;
11574            app.instrumentationArguments = arguments;
11575            app.instrumentationWatcher = watcher;
11576            app.instrumentationResultClass = className;
11577            Binder.restoreCallingIdentity(origId);
11578        }
11579
11580        return true;
11581    }
11582
11583    /**
11584     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11585     * error to the logs, but if somebody is watching, send the report there too.  This enables
11586     * the "am" command to report errors with more information.
11587     *
11588     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11589     * @param cn The component name of the instrumentation.
11590     * @param report The error report.
11591     */
11592    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11593            ComponentName cn, String report) {
11594        Slog.w(TAG, report);
11595        try {
11596            if (watcher != null) {
11597                Bundle results = new Bundle();
11598                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11599                results.putString("Error", report);
11600                watcher.instrumentationStatus(cn, -1, results);
11601            }
11602        } catch (RemoteException e) {
11603            Slog.w(TAG, e);
11604        }
11605    }
11606
11607    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11608        if (app.instrumentationWatcher != null) {
11609            try {
11610                // NOTE:  IInstrumentationWatcher *must* be oneway here
11611                app.instrumentationWatcher.instrumentationFinished(
11612                    app.instrumentationClass,
11613                    resultCode,
11614                    results);
11615            } catch (RemoteException e) {
11616            }
11617        }
11618        app.instrumentationWatcher = null;
11619        app.instrumentationClass = null;
11620        app.instrumentationInfo = null;
11621        app.instrumentationProfileFile = null;
11622        app.instrumentationArguments = null;
11623
11624        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11625    }
11626
11627    public void finishInstrumentation(IApplicationThread target,
11628            int resultCode, Bundle results) {
11629        int userId = UserHandle.getCallingUserId();
11630        // Refuse possible leaked file descriptors
11631        if (results != null && results.hasFileDescriptors()) {
11632            throw new IllegalArgumentException("File descriptors passed in Intent");
11633        }
11634
11635        synchronized(this) {
11636            ProcessRecord app = getRecordForAppLocked(target);
11637            if (app == null) {
11638                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11639                return;
11640            }
11641            final long origId = Binder.clearCallingIdentity();
11642            finishInstrumentationLocked(app, resultCode, results);
11643            Binder.restoreCallingIdentity(origId);
11644        }
11645    }
11646
11647    // =========================================================
11648    // CONFIGURATION
11649    // =========================================================
11650
11651    public ConfigurationInfo getDeviceConfigurationInfo() {
11652        ConfigurationInfo config = new ConfigurationInfo();
11653        synchronized (this) {
11654            config.reqTouchScreen = mConfiguration.touchscreen;
11655            config.reqKeyboardType = mConfiguration.keyboard;
11656            config.reqNavigation = mConfiguration.navigation;
11657            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11658                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11659                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11660            }
11661            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11662                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11663                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11664            }
11665            config.reqGlEsVersion = GL_ES_VERSION;
11666        }
11667        return config;
11668    }
11669
11670    public Configuration getConfiguration() {
11671        Configuration ci;
11672        synchronized(this) {
11673            ci = new Configuration(mConfiguration);
11674        }
11675        return ci;
11676    }
11677
11678    public void updatePersistentConfiguration(Configuration values) {
11679        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11680                "updateConfiguration()");
11681        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11682                "updateConfiguration()");
11683        if (values == null) {
11684            throw new NullPointerException("Configuration must not be null");
11685        }
11686
11687        synchronized(this) {
11688            final long origId = Binder.clearCallingIdentity();
11689            updateConfigurationLocked(values, null, true, false);
11690            Binder.restoreCallingIdentity(origId);
11691        }
11692    }
11693
11694    public void updateConfiguration(Configuration values) {
11695        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11696                "updateConfiguration()");
11697
11698        synchronized(this) {
11699            if (values == null && mWindowManager != null) {
11700                // sentinel: fetch the current configuration from the window manager
11701                values = mWindowManager.computeNewConfiguration();
11702            }
11703
11704            if (mWindowManager != null) {
11705                mProcessList.applyDisplaySize(mWindowManager);
11706            }
11707
11708            final long origId = Binder.clearCallingIdentity();
11709            if (values != null) {
11710                Settings.System.clearConfiguration(values);
11711            }
11712            updateConfigurationLocked(values, null, false, false);
11713            Binder.restoreCallingIdentity(origId);
11714        }
11715    }
11716
11717    /**
11718     * Do either or both things: (1) change the current configuration, and (2)
11719     * make sure the given activity is running with the (now) current
11720     * configuration.  Returns true if the activity has been left running, or
11721     * false if <var>starting</var> is being destroyed to match the new
11722     * configuration.
11723     * @param persistent TODO
11724     */
11725    boolean updateConfigurationLocked(Configuration values,
11726            ActivityRecord starting, boolean persistent, boolean initLocale) {
11727        // do nothing if we are headless
11728        if (mHeadless) return true;
11729
11730        int changes = 0;
11731
11732        boolean kept = true;
11733
11734        if (values != null) {
11735            Configuration newConfig = new Configuration(mConfiguration);
11736            changes = newConfig.updateFrom(values);
11737            if (changes != 0) {
11738                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11739                    Slog.i(TAG, "Updating configuration to: " + values);
11740                }
11741
11742                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11743
11744                if (values.locale != null && !initLocale) {
11745                    saveLocaleLocked(values.locale,
11746                                     !values.locale.equals(mConfiguration.locale),
11747                                     values.userSetLocale);
11748                }
11749
11750                mConfigurationSeq++;
11751                if (mConfigurationSeq <= 0) {
11752                    mConfigurationSeq = 1;
11753                }
11754                newConfig.seq = mConfigurationSeq;
11755                mConfiguration = newConfig;
11756                Slog.i(TAG, "Config changed: " + newConfig);
11757
11758                final Configuration configCopy = new Configuration(mConfiguration);
11759
11760                // TODO: If our config changes, should we auto dismiss any currently
11761                // showing dialogs?
11762                mShowDialogs = shouldShowDialogs(newConfig);
11763
11764                AttributeCache ac = AttributeCache.instance();
11765                if (ac != null) {
11766                    ac.updateConfiguration(configCopy);
11767                }
11768
11769                // Make sure all resources in our process are updated
11770                // right now, so that anyone who is going to retrieve
11771                // resource values after we return will be sure to get
11772                // the new ones.  This is especially important during
11773                // boot, where the first config change needs to guarantee
11774                // all resources have that config before following boot
11775                // code is executed.
11776                mSystemThread.applyConfigurationToResources(configCopy);
11777
11778                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11779                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11780                    msg.obj = new Configuration(configCopy);
11781                    mHandler.sendMessage(msg);
11782                }
11783
11784                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11785                    ProcessRecord app = mLruProcesses.get(i);
11786                    try {
11787                        if (app.thread != null) {
11788                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11789                                    + app.processName + " new config " + mConfiguration);
11790                            app.thread.scheduleConfigurationChanged(configCopy);
11791                        }
11792                    } catch (Exception e) {
11793                    }
11794                }
11795                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11796                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11797                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11798                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11799                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11800                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11801                    broadcastIntentLocked(null, null,
11802                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11803                            null, null, 0, null, null,
11804                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11805                }
11806            }
11807        }
11808
11809        if (changes != 0 && starting == null) {
11810            // If the configuration changed, and the caller is not already
11811            // in the process of starting an activity, then find the top
11812            // activity to check if its configuration needs to change.
11813            starting = mMainStack.topRunningActivityLocked(null);
11814        }
11815
11816        if (starting != null) {
11817            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11818            // And we need to make sure at this point that all other activities
11819            // are made visible with the correct configuration.
11820            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11821        }
11822
11823        if (values != null && mWindowManager != null) {
11824            mWindowManager.setNewConfiguration(mConfiguration);
11825        }
11826
11827        return kept;
11828    }
11829
11830    /**
11831     * Decide based on the configuration whether we should shouw the ANR,
11832     * crash, etc dialogs.  The idea is that if there is no affordnace to
11833     * press the on-screen buttons, we shouldn't show the dialog.
11834     *
11835     * A thought: SystemUI might also want to get told about this, the Power
11836     * dialog / global actions also might want different behaviors.
11837     */
11838    private static final boolean shouldShowDialogs(Configuration config) {
11839        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11840                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11841    }
11842
11843    /**
11844     * Save the locale.  You must be inside a synchronized (this) block.
11845     */
11846    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11847        if(isDiff) {
11848            SystemProperties.set("user.language", l.getLanguage());
11849            SystemProperties.set("user.region", l.getCountry());
11850        }
11851
11852        if(isPersist) {
11853            SystemProperties.set("persist.sys.language", l.getLanguage());
11854            SystemProperties.set("persist.sys.country", l.getCountry());
11855            SystemProperties.set("persist.sys.localevar", l.getVariant());
11856        }
11857    }
11858
11859    @Override
11860    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11861        ActivityRecord srec = ActivityRecord.forToken(token);
11862        return srec != null && srec.task.affinity != null &&
11863                srec.task.affinity.equals(destAffinity);
11864    }
11865
11866    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11867            Intent resultData) {
11868        ComponentName dest = destIntent.getComponent();
11869
11870        synchronized (this) {
11871            ActivityRecord srec = ActivityRecord.forToken(token);
11872            if (srec == null) {
11873                return false;
11874            }
11875            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11876            final int start = history.indexOf(srec);
11877            if (start < 0) {
11878                // Current activity is not in history stack; do nothing.
11879                return false;
11880            }
11881            int finishTo = start - 1;
11882            ActivityRecord parent = null;
11883            boolean foundParentInTask = false;
11884            if (dest != null) {
11885                TaskRecord tr = srec.task;
11886                for (int i = start - 1; i >= 0; i--) {
11887                    ActivityRecord r = history.get(i);
11888                    if (tr != r.task) {
11889                        // Couldn't find parent in the same task; stop at the one above this.
11890                        // (Root of current task; in-app "home" behavior)
11891                        // Always at least finish the current activity.
11892                        finishTo = Math.min(start - 1, i + 1);
11893                        parent = history.get(finishTo);
11894                        break;
11895                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11896                            r.info.name.equals(dest.getClassName())) {
11897                        finishTo = i;
11898                        parent = r;
11899                        foundParentInTask = true;
11900                        break;
11901                    }
11902                }
11903            }
11904
11905            if (mController != null) {
11906                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11907                if (next != null) {
11908                    // ask watcher if this is allowed
11909                    boolean resumeOK = true;
11910                    try {
11911                        resumeOK = mController.activityResuming(next.packageName);
11912                    } catch (RemoteException e) {
11913                        mController = null;
11914                    }
11915
11916                    if (!resumeOK) {
11917                        return false;
11918                    }
11919                }
11920            }
11921            final long origId = Binder.clearCallingIdentity();
11922            for (int i = start; i > finishTo; i--) {
11923                ActivityRecord r = history.get(i);
11924                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11925                        "navigate-up");
11926                // Only return the supplied result for the first activity finished
11927                resultCode = Activity.RESULT_CANCELED;
11928                resultData = null;
11929            }
11930
11931            if (parent != null && foundParentInTask) {
11932                final int parentLaunchMode = parent.info.launchMode;
11933                final int destIntentFlags = destIntent.getFlags();
11934                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11935                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11936                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11937                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11938                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11939                } else {
11940                    try {
11941                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11942                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11943                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11944                                null, aInfo, parent.appToken, null,
11945                                0, -1, parent.launchedFromUid, 0, null, true, null);
11946                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11947                    } catch (RemoteException e) {
11948                        foundParentInTask = false;
11949                    }
11950                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11951                            resultData, "navigate-up");
11952                }
11953            }
11954            Binder.restoreCallingIdentity(origId);
11955            return foundParentInTask;
11956        }
11957    }
11958
11959    public int getLaunchedFromUid(IBinder activityToken) {
11960        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11961        if (srec == null) {
11962            return -1;
11963        }
11964        return srec.launchedFromUid;
11965    }
11966
11967    // =========================================================
11968    // LIFETIME MANAGEMENT
11969    // =========================================================
11970
11971    // Returns which broadcast queue the app is the current [or imminent] receiver
11972    // on, or 'null' if the app is not an active broadcast recipient.
11973    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11974        BroadcastRecord r = app.curReceiver;
11975        if (r != null) {
11976            return r.queue;
11977        }
11978
11979        // It's not the current receiver, but it might be starting up to become one
11980        synchronized (this) {
11981            for (BroadcastQueue queue : mBroadcastQueues) {
11982                r = queue.mPendingBroadcast;
11983                if (r != null && r.curApp == app) {
11984                    // found it; report which queue it's in
11985                    return queue;
11986                }
11987            }
11988        }
11989
11990        return null;
11991    }
11992
11993    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11994            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11995        if (mAdjSeq == app.adjSeq) {
11996            // This adjustment has already been computed.  If we are calling
11997            // from the top, we may have already computed our adjustment with
11998            // an earlier hidden adjustment that isn't really for us... if
11999            // so, use the new hidden adjustment.
12000            if (!recursed && app.hidden) {
12001                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12002                        app.hasActivities ? hiddenAdj : emptyAdj;
12003            }
12004            return app.curRawAdj;
12005        }
12006
12007        if (app.thread == null) {
12008            app.adjSeq = mAdjSeq;
12009            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12010            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12011        }
12012
12013        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12014        app.adjSource = null;
12015        app.adjTarget = null;
12016        app.empty = false;
12017        app.hidden = false;
12018
12019        final int activitiesSize = app.activities.size();
12020
12021        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12022            // The max adjustment doesn't allow this app to be anything
12023            // below foreground, so it is not worth doing work for it.
12024            app.adjType = "fixed";
12025            app.adjSeq = mAdjSeq;
12026            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12027            app.hasActivities = false;
12028            app.foregroundActivities = false;
12029            app.keeping = true;
12030            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12031            // System process can do UI, and when they do we want to have
12032            // them trim their memory after the user leaves the UI.  To
12033            // facilitate this, here we need to determine whether or not it
12034            // is currently showing UI.
12035            app.systemNoUi = true;
12036            if (app == TOP_APP) {
12037                app.systemNoUi = false;
12038                app.hasActivities = true;
12039            } else if (activitiesSize > 0) {
12040                for (int j = 0; j < activitiesSize; j++) {
12041                    final ActivityRecord r = app.activities.get(j);
12042                    if (r.visible) {
12043                        app.systemNoUi = false;
12044                    }
12045                    if (r.app == app) {
12046                        app.hasActivities = true;
12047                    }
12048                }
12049            }
12050            return (app.curAdj=app.maxAdj);
12051        }
12052
12053        app.keeping = false;
12054        app.systemNoUi = false;
12055        app.hasActivities = false;
12056
12057        // Determine the importance of the process, starting with most
12058        // important to least, and assign an appropriate OOM adjustment.
12059        int adj;
12060        int schedGroup;
12061        boolean foregroundActivities = false;
12062        boolean interesting = false;
12063        BroadcastQueue queue;
12064        if (app == TOP_APP) {
12065            // The last app on the list is the foreground app.
12066            adj = ProcessList.FOREGROUND_APP_ADJ;
12067            schedGroup = Process.THREAD_GROUP_DEFAULT;
12068            app.adjType = "top-activity";
12069            foregroundActivities = true;
12070            interesting = true;
12071            app.hasActivities = true;
12072        } else if (app.instrumentationClass != null) {
12073            // Don't want to kill running instrumentation.
12074            adj = ProcessList.FOREGROUND_APP_ADJ;
12075            schedGroup = Process.THREAD_GROUP_DEFAULT;
12076            app.adjType = "instrumentation";
12077            interesting = true;
12078        } else if ((queue = isReceivingBroadcast(app)) != null) {
12079            // An app that is currently receiving a broadcast also
12080            // counts as being in the foreground for OOM killer purposes.
12081            // It's placed in a sched group based on the nature of the
12082            // broadcast as reflected by which queue it's active in.
12083            adj = ProcessList.FOREGROUND_APP_ADJ;
12084            schedGroup = (queue == mFgBroadcastQueue)
12085                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12086            app.adjType = "broadcast";
12087        } else if (app.executingServices.size() > 0) {
12088            // An app that is currently executing a service callback also
12089            // counts as being in the foreground.
12090            adj = ProcessList.FOREGROUND_APP_ADJ;
12091            schedGroup = Process.THREAD_GROUP_DEFAULT;
12092            app.adjType = "exec-service";
12093        } else {
12094            // Assume process is hidden (has activities); we will correct
12095            // later if this is not the case.
12096            adj = hiddenAdj;
12097            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12098            app.hidden = true;
12099            app.adjType = "bg-activities";
12100        }
12101
12102        boolean hasStoppingActivities = false;
12103
12104        // Examine all activities if not already foreground.
12105        if (!foregroundActivities && activitiesSize > 0) {
12106            for (int j = 0; j < activitiesSize; j++) {
12107                final ActivityRecord r = app.activities.get(j);
12108                if (r.visible) {
12109                    // App has a visible activity; only upgrade adjustment.
12110                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12111                        adj = ProcessList.VISIBLE_APP_ADJ;
12112                        app.adjType = "visible";
12113                    }
12114                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12115                    app.hidden = false;
12116                    app.hasActivities = true;
12117                    foregroundActivities = true;
12118                    break;
12119                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12120                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12121                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12122                        app.adjType = "pausing";
12123                    }
12124                    app.hidden = false;
12125                    foregroundActivities = true;
12126                } else if (r.state == ActivityState.STOPPING) {
12127                    // We will apply the actual adjustment later, because
12128                    // we want to allow this process to immediately go through
12129                    // any memory trimming that is in effect.
12130                    app.hidden = false;
12131                    foregroundActivities = true;
12132                    hasStoppingActivities = true;
12133                }
12134                if (r.app == app) {
12135                    app.hasActivities = true;
12136                }
12137            }
12138        }
12139
12140        if (adj == hiddenAdj && !app.hasActivities) {
12141            // Whoops, this process is completely empty as far as we know
12142            // at this point.
12143            adj = emptyAdj;
12144            app.empty = true;
12145            app.adjType = "bg-empty";
12146        }
12147
12148        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12149            if (app.foregroundServices) {
12150                // The user is aware of this app, so make it visible.
12151                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12152                app.hidden = false;
12153                app.adjType = "foreground-service";
12154                schedGroup = Process.THREAD_GROUP_DEFAULT;
12155            } else if (app.forcingToForeground != null) {
12156                // The user is aware of this app, so make it visible.
12157                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12158                app.hidden = false;
12159                app.adjType = "force-foreground";
12160                app.adjSource = app.forcingToForeground;
12161                schedGroup = Process.THREAD_GROUP_DEFAULT;
12162            }
12163        }
12164
12165        if (app.foregroundServices) {
12166            interesting = true;
12167        }
12168
12169        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12170            // We don't want to kill the current heavy-weight process.
12171            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12172            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12173            app.hidden = false;
12174            app.adjType = "heavy";
12175        }
12176
12177        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12178            // This process is hosting what we currently consider to be the
12179            // home app, so we don't want to let it go into the background.
12180            adj = ProcessList.HOME_APP_ADJ;
12181            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12182            app.hidden = false;
12183            app.adjType = "home";
12184        }
12185
12186        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12187                && app.activities.size() > 0) {
12188            // This was the previous process that showed UI to the user.
12189            // We want to try to keep it around more aggressively, to give
12190            // a good experience around switching between two apps.
12191            adj = ProcessList.PREVIOUS_APP_ADJ;
12192            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12193            app.hidden = false;
12194            app.adjType = "previous";
12195        }
12196
12197        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12198                + " reason=" + app.adjType);
12199
12200        // By default, we use the computed adjustment.  It may be changed if
12201        // there are applications dependent on our services or providers, but
12202        // this gives us a baseline and makes sure we don't get into an
12203        // infinite recursion.
12204        app.adjSeq = mAdjSeq;
12205        app.curRawAdj = app.nonStoppingAdj = adj;
12206
12207        if (mBackupTarget != null && app == mBackupTarget.app) {
12208            // If possible we want to avoid killing apps while they're being backed up
12209            if (adj > ProcessList.BACKUP_APP_ADJ) {
12210                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12211                adj = ProcessList.BACKUP_APP_ADJ;
12212                app.adjType = "backup";
12213                app.hidden = false;
12214            }
12215        }
12216
12217        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12218                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12219            final long now = SystemClock.uptimeMillis();
12220            // This process is more important if the top activity is
12221            // bound to the service.
12222            Iterator<ServiceRecord> jt = app.services.iterator();
12223            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12224                ServiceRecord s = jt.next();
12225                if (s.startRequested) {
12226                    if (app.hasShownUi && app != mHomeProcess) {
12227                        // If this process has shown some UI, let it immediately
12228                        // go to the LRU list because it may be pretty heavy with
12229                        // UI stuff.  We'll tag it with a label just to help
12230                        // debug and understand what is going on.
12231                        if (adj > ProcessList.SERVICE_ADJ) {
12232                            app.adjType = "started-bg-ui-services";
12233                        }
12234                    } else {
12235                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12236                            // This service has seen some activity within
12237                            // recent memory, so we will keep its process ahead
12238                            // of the background processes.
12239                            if (adj > ProcessList.SERVICE_ADJ) {
12240                                adj = ProcessList.SERVICE_ADJ;
12241                                app.adjType = "started-services";
12242                                app.hidden = false;
12243                            }
12244                        }
12245                        // If we have let the service slide into the background
12246                        // state, still have some text describing what it is doing
12247                        // even though the service no longer has an impact.
12248                        if (adj > ProcessList.SERVICE_ADJ) {
12249                            app.adjType = "started-bg-services";
12250                        }
12251                    }
12252                    // Don't kill this process because it is doing work; it
12253                    // has said it is doing work.
12254                    app.keeping = true;
12255                }
12256                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12257                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12258                    Iterator<ArrayList<ConnectionRecord>> kt
12259                            = s.connections.values().iterator();
12260                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12261                        ArrayList<ConnectionRecord> clist = kt.next();
12262                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12263                            // XXX should compute this based on the max of
12264                            // all connected clients.
12265                            ConnectionRecord cr = clist.get(i);
12266                            if (cr.binding.client == app) {
12267                                // Binding to ourself is not interesting.
12268                                continue;
12269                            }
12270                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12271                                ProcessRecord client = cr.binding.client;
12272                                int clientAdj = adj;
12273                                int myHiddenAdj = hiddenAdj;
12274                                if (myHiddenAdj > client.hiddenAdj) {
12275                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12276                                        myHiddenAdj = client.hiddenAdj;
12277                                    } else {
12278                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12279                                    }
12280                                }
12281                                int myEmptyAdj = emptyAdj;
12282                                if (myEmptyAdj > client.emptyAdj) {
12283                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12284                                        myEmptyAdj = client.emptyAdj;
12285                                    } else {
12286                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12287                                    }
12288                                }
12289                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12290                                        myEmptyAdj, TOP_APP, true, doingAll);
12291                                String adjType = null;
12292                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12293                                    // Not doing bind OOM management, so treat
12294                                    // this guy more like a started service.
12295                                    if (app.hasShownUi && app != mHomeProcess) {
12296                                        // If this process has shown some UI, let it immediately
12297                                        // go to the LRU list because it may be pretty heavy with
12298                                        // UI stuff.  We'll tag it with a label just to help
12299                                        // debug and understand what is going on.
12300                                        if (adj > clientAdj) {
12301                                            adjType = "bound-bg-ui-services";
12302                                        }
12303                                        app.hidden = false;
12304                                        clientAdj = adj;
12305                                    } else {
12306                                        if (now >= (s.lastActivity
12307                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12308                                            // This service has not seen activity within
12309                                            // recent memory, so allow it to drop to the
12310                                            // LRU list if there is no other reason to keep
12311                                            // it around.  We'll also tag it with a label just
12312                                            // to help debug and undertand what is going on.
12313                                            if (adj > clientAdj) {
12314                                                adjType = "bound-bg-services";
12315                                            }
12316                                            clientAdj = adj;
12317                                        }
12318                                    }
12319                                }
12320                                if (adj > clientAdj) {
12321                                    // If this process has recently shown UI, and
12322                                    // the process that is binding to it is less
12323                                    // important than being visible, then we don't
12324                                    // care about the binding as much as we care
12325                                    // about letting this process get into the LRU
12326                                    // list to be killed and restarted if needed for
12327                                    // memory.
12328                                    if (app.hasShownUi && app != mHomeProcess
12329                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12330                                        adjType = "bound-bg-ui-services";
12331                                    } else {
12332                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12333                                                |Context.BIND_IMPORTANT)) != 0) {
12334                                            adj = clientAdj;
12335                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12336                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12337                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12338                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12339                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12340                                            adj = clientAdj;
12341                                        } else {
12342                                            app.pendingUiClean = true;
12343                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12344                                                adj = ProcessList.VISIBLE_APP_ADJ;
12345                                            }
12346                                        }
12347                                        if (!client.hidden) {
12348                                            app.hidden = false;
12349                                        }
12350                                        if (client.keeping) {
12351                                            app.keeping = true;
12352                                        }
12353                                        adjType = "service";
12354                                    }
12355                                }
12356                                if (adjType != null) {
12357                                    app.adjType = adjType;
12358                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12359                                            .REASON_SERVICE_IN_USE;
12360                                    app.adjSource = cr.binding.client;
12361                                    app.adjSourceOom = clientAdj;
12362                                    app.adjTarget = s.name;
12363                                }
12364                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12365                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12366                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12367                                    }
12368                                }
12369                            }
12370                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12371                                ActivityRecord a = cr.activity;
12372                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12373                                        (a.visible || a.state == ActivityState.RESUMED
12374                                         || a.state == ActivityState.PAUSING)) {
12375                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12376                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12377                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12378                                    }
12379                                    app.hidden = false;
12380                                    app.adjType = "service";
12381                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12382                                            .REASON_SERVICE_IN_USE;
12383                                    app.adjSource = a;
12384                                    app.adjSourceOom = adj;
12385                                    app.adjTarget = s.name;
12386                                }
12387                            }
12388                        }
12389                    }
12390                }
12391            }
12392
12393            // Finally, if this process has active services running in it, we
12394            // would like to avoid killing it unless it would prevent the current
12395            // application from running.  By default we put the process in
12396            // with the rest of the background processes; as we scan through
12397            // its services we may bump it up from there.
12398            if (adj > hiddenAdj) {
12399                adj = hiddenAdj;
12400                app.hidden = false;
12401                app.adjType = "bg-services";
12402            }
12403        }
12404
12405        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12406                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12407            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12408            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12409                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12410                ContentProviderRecord cpr = jt.next();
12411                for (int i = cpr.connections.size()-1;
12412                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12413                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12414                        i--) {
12415                    ContentProviderConnection conn = cpr.connections.get(i);
12416                    ProcessRecord client = conn.client;
12417                    if (client == app) {
12418                        // Being our own client is not interesting.
12419                        continue;
12420                    }
12421                    int myHiddenAdj = hiddenAdj;
12422                    if (myHiddenAdj > client.hiddenAdj) {
12423                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12424                            myHiddenAdj = client.hiddenAdj;
12425                        } else {
12426                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12427                        }
12428                    }
12429                    int myEmptyAdj = emptyAdj;
12430                    if (myEmptyAdj > client.emptyAdj) {
12431                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12432                            myEmptyAdj = client.emptyAdj;
12433                        } else {
12434                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12435                        }
12436                    }
12437                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12438                            myEmptyAdj, TOP_APP, true, doingAll);
12439                    if (adj > clientAdj) {
12440                        if (app.hasShownUi && app != mHomeProcess
12441                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12442                            app.adjType = "bg-ui-provider";
12443                        } else {
12444                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12445                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12446                            app.adjType = "provider";
12447                        }
12448                        if (!client.hidden) {
12449                            app.hidden = false;
12450                        }
12451                        if (client.keeping) {
12452                            app.keeping = true;
12453                        }
12454                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12455                                .REASON_PROVIDER_IN_USE;
12456                        app.adjSource = client;
12457                        app.adjSourceOom = clientAdj;
12458                        app.adjTarget = cpr.name;
12459                    }
12460                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12461                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12462                    }
12463                }
12464                // If the provider has external (non-framework) process
12465                // dependencies, ensure that its adjustment is at least
12466                // FOREGROUND_APP_ADJ.
12467                if (cpr.hasExternalProcessHandles()) {
12468                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12469                        adj = ProcessList.FOREGROUND_APP_ADJ;
12470                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12471                        app.hidden = false;
12472                        app.keeping = true;
12473                        app.adjType = "provider";
12474                        app.adjTarget = cpr.name;
12475                    }
12476                }
12477            }
12478        }
12479
12480        if (adj == ProcessList.SERVICE_ADJ) {
12481            if (doingAll) {
12482                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12483                mNewNumServiceProcs++;
12484            }
12485            if (app.serviceb) {
12486                adj = ProcessList.SERVICE_B_ADJ;
12487            }
12488        } else {
12489            app.serviceb = false;
12490        }
12491
12492        app.nonStoppingAdj = adj;
12493
12494        if (hasStoppingActivities) {
12495            // Only upgrade adjustment.
12496            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12497                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12498                app.adjType = "stopping";
12499            }
12500        }
12501
12502        app.curRawAdj = adj;
12503
12504        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12505        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12506        if (adj > app.maxAdj) {
12507            adj = app.maxAdj;
12508            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12509                schedGroup = Process.THREAD_GROUP_DEFAULT;
12510            }
12511        }
12512        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12513            app.keeping = true;
12514        }
12515
12516        if (app.hasAboveClient) {
12517            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12518            // then we need to drop its adjustment to be lower than the service's
12519            // in order to honor the request.  We want to drop it by one adjustment
12520            // level...  but there is special meaning applied to various levels so
12521            // we will skip some of them.
12522            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12523                // System process will not get dropped, ever
12524            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12525                adj = ProcessList.VISIBLE_APP_ADJ;
12526            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12527                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12528            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12529                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12530            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12531                adj++;
12532            }
12533        }
12534
12535        int importance = app.memImportance;
12536        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12537            app.curAdj = adj;
12538            app.curSchedGroup = schedGroup;
12539            if (!interesting) {
12540                // For this reporting, if there is not something explicitly
12541                // interesting in this process then we will push it to the
12542                // background importance.
12543                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12544            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12545                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12546            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12547                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12548            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12549                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12550            } else if (adj >= ProcessList.SERVICE_ADJ) {
12551                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12552            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12553                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12554            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12555                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12556            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12557                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12558            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12559                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12560            } else {
12561                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12562            }
12563        }
12564
12565        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12566        if (foregroundActivities != app.foregroundActivities) {
12567            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12568        }
12569        if (changes != 0) {
12570            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12571            app.memImportance = importance;
12572            app.foregroundActivities = foregroundActivities;
12573            int i = mPendingProcessChanges.size()-1;
12574            ProcessChangeItem item = null;
12575            while (i >= 0) {
12576                item = mPendingProcessChanges.get(i);
12577                if (item.pid == app.pid) {
12578                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12579                    break;
12580                }
12581                i--;
12582            }
12583            if (i < 0) {
12584                // No existing item in pending changes; need a new one.
12585                final int NA = mAvailProcessChanges.size();
12586                if (NA > 0) {
12587                    item = mAvailProcessChanges.remove(NA-1);
12588                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12589                } else {
12590                    item = new ProcessChangeItem();
12591                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12592                }
12593                item.changes = 0;
12594                item.pid = app.pid;
12595                item.uid = app.info.uid;
12596                if (mPendingProcessChanges.size() == 0) {
12597                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12598                            "*** Enqueueing dispatch processes changed!");
12599                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12600                }
12601                mPendingProcessChanges.add(item);
12602            }
12603            item.changes |= changes;
12604            item.importance = importance;
12605            item.foregroundActivities = foregroundActivities;
12606            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12607                    + Integer.toHexString(System.identityHashCode(item))
12608                    + " " + app.toShortString() + ": changes=" + item.changes
12609                    + " importance=" + item.importance
12610                    + " foreground=" + item.foregroundActivities
12611                    + " type=" + app.adjType + " source=" + app.adjSource
12612                    + " target=" + app.adjTarget);
12613        }
12614
12615        return app.curRawAdj;
12616    }
12617
12618    /**
12619     * Ask a given process to GC right now.
12620     */
12621    final void performAppGcLocked(ProcessRecord app) {
12622        try {
12623            app.lastRequestedGc = SystemClock.uptimeMillis();
12624            if (app.thread != null) {
12625                if (app.reportLowMemory) {
12626                    app.reportLowMemory = false;
12627                    app.thread.scheduleLowMemory();
12628                } else {
12629                    app.thread.processInBackground();
12630                }
12631            }
12632        } catch (Exception e) {
12633            // whatever.
12634        }
12635    }
12636
12637    /**
12638     * Returns true if things are idle enough to perform GCs.
12639     */
12640    private final boolean canGcNowLocked() {
12641        boolean processingBroadcasts = false;
12642        for (BroadcastQueue q : mBroadcastQueues) {
12643            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12644                processingBroadcasts = true;
12645            }
12646        }
12647        return !processingBroadcasts
12648                && (mSleeping || (mMainStack.mResumedActivity != null &&
12649                        mMainStack.mResumedActivity.idle));
12650    }
12651
12652    /**
12653     * Perform GCs on all processes that are waiting for it, but only
12654     * if things are idle.
12655     */
12656    final void performAppGcsLocked() {
12657        final int N = mProcessesToGc.size();
12658        if (N <= 0) {
12659            return;
12660        }
12661        if (canGcNowLocked()) {
12662            while (mProcessesToGc.size() > 0) {
12663                ProcessRecord proc = mProcessesToGc.remove(0);
12664                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12665                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12666                            <= SystemClock.uptimeMillis()) {
12667                        // To avoid spamming the system, we will GC processes one
12668                        // at a time, waiting a few seconds between each.
12669                        performAppGcLocked(proc);
12670                        scheduleAppGcsLocked();
12671                        return;
12672                    } else {
12673                        // It hasn't been long enough since we last GCed this
12674                        // process...  put it in the list to wait for its time.
12675                        addProcessToGcListLocked(proc);
12676                        break;
12677                    }
12678                }
12679            }
12680
12681            scheduleAppGcsLocked();
12682        }
12683    }
12684
12685    /**
12686     * If all looks good, perform GCs on all processes waiting for them.
12687     */
12688    final void performAppGcsIfAppropriateLocked() {
12689        if (canGcNowLocked()) {
12690            performAppGcsLocked();
12691            return;
12692        }
12693        // Still not idle, wait some more.
12694        scheduleAppGcsLocked();
12695    }
12696
12697    /**
12698     * Schedule the execution of all pending app GCs.
12699     */
12700    final void scheduleAppGcsLocked() {
12701        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12702
12703        if (mProcessesToGc.size() > 0) {
12704            // Schedule a GC for the time to the next process.
12705            ProcessRecord proc = mProcessesToGc.get(0);
12706            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12707
12708            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12709            long now = SystemClock.uptimeMillis();
12710            if (when < (now+GC_TIMEOUT)) {
12711                when = now + GC_TIMEOUT;
12712            }
12713            mHandler.sendMessageAtTime(msg, when);
12714        }
12715    }
12716
12717    /**
12718     * Add a process to the array of processes waiting to be GCed.  Keeps the
12719     * list in sorted order by the last GC time.  The process can't already be
12720     * on the list.
12721     */
12722    final void addProcessToGcListLocked(ProcessRecord proc) {
12723        boolean added = false;
12724        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12725            if (mProcessesToGc.get(i).lastRequestedGc <
12726                    proc.lastRequestedGc) {
12727                added = true;
12728                mProcessesToGc.add(i+1, proc);
12729                break;
12730            }
12731        }
12732        if (!added) {
12733            mProcessesToGc.add(0, proc);
12734        }
12735    }
12736
12737    /**
12738     * Set up to ask a process to GC itself.  This will either do it
12739     * immediately, or put it on the list of processes to gc the next
12740     * time things are idle.
12741     */
12742    final void scheduleAppGcLocked(ProcessRecord app) {
12743        long now = SystemClock.uptimeMillis();
12744        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12745            return;
12746        }
12747        if (!mProcessesToGc.contains(app)) {
12748            addProcessToGcListLocked(app);
12749            scheduleAppGcsLocked();
12750        }
12751    }
12752
12753    final void checkExcessivePowerUsageLocked(boolean doKills) {
12754        updateCpuStatsNow();
12755
12756        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12757        boolean doWakeKills = doKills;
12758        boolean doCpuKills = doKills;
12759        if (mLastPowerCheckRealtime == 0) {
12760            doWakeKills = false;
12761        }
12762        if (mLastPowerCheckUptime == 0) {
12763            doCpuKills = false;
12764        }
12765        if (stats.isScreenOn()) {
12766            doWakeKills = false;
12767        }
12768        final long curRealtime = SystemClock.elapsedRealtime();
12769        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12770        final long curUptime = SystemClock.uptimeMillis();
12771        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12772        mLastPowerCheckRealtime = curRealtime;
12773        mLastPowerCheckUptime = curUptime;
12774        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12775            doWakeKills = false;
12776        }
12777        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12778            doCpuKills = false;
12779        }
12780        int i = mLruProcesses.size();
12781        while (i > 0) {
12782            i--;
12783            ProcessRecord app = mLruProcesses.get(i);
12784            if (!app.keeping) {
12785                long wtime;
12786                synchronized (stats) {
12787                    wtime = stats.getProcessWakeTime(app.info.uid,
12788                            app.pid, curRealtime);
12789                }
12790                long wtimeUsed = wtime - app.lastWakeTime;
12791                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12792                if (DEBUG_POWER) {
12793                    StringBuilder sb = new StringBuilder(128);
12794                    sb.append("Wake for ");
12795                    app.toShortString(sb);
12796                    sb.append(": over ");
12797                    TimeUtils.formatDuration(realtimeSince, sb);
12798                    sb.append(" used ");
12799                    TimeUtils.formatDuration(wtimeUsed, sb);
12800                    sb.append(" (");
12801                    sb.append((wtimeUsed*100)/realtimeSince);
12802                    sb.append("%)");
12803                    Slog.i(TAG, sb.toString());
12804                    sb.setLength(0);
12805                    sb.append("CPU for ");
12806                    app.toShortString(sb);
12807                    sb.append(": over ");
12808                    TimeUtils.formatDuration(uptimeSince, sb);
12809                    sb.append(" used ");
12810                    TimeUtils.formatDuration(cputimeUsed, sb);
12811                    sb.append(" (");
12812                    sb.append((cputimeUsed*100)/uptimeSince);
12813                    sb.append("%)");
12814                    Slog.i(TAG, sb.toString());
12815                }
12816                // If a process has held a wake lock for more
12817                // than 50% of the time during this period,
12818                // that sounds bad.  Kill!
12819                if (doWakeKills && realtimeSince > 0
12820                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12821                    synchronized (stats) {
12822                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12823                                realtimeSince, wtimeUsed);
12824                    }
12825                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12826                            + " (pid " + app.pid + "): held " + wtimeUsed
12827                            + " during " + realtimeSince);
12828                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12829                            app.processName, app.setAdj, "excessive wake lock");
12830                    Process.killProcessQuiet(app.pid);
12831                } else if (doCpuKills && uptimeSince > 0
12832                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12833                    synchronized (stats) {
12834                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12835                                uptimeSince, cputimeUsed);
12836                    }
12837                    Slog.w(TAG, "Excessive CPU in " + app.processName
12838                            + " (pid " + app.pid + "): used " + cputimeUsed
12839                            + " during " + uptimeSince);
12840                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12841                            app.processName, app.setAdj, "excessive cpu");
12842                    Process.killProcessQuiet(app.pid);
12843                } else {
12844                    app.lastWakeTime = wtime;
12845                    app.lastCpuTime = app.curCpuTime;
12846                }
12847            }
12848        }
12849    }
12850
12851    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12852            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12853        app.hiddenAdj = hiddenAdj;
12854        app.emptyAdj = emptyAdj;
12855
12856        if (app.thread == null) {
12857            return false;
12858        }
12859
12860        final boolean wasKeeping = app.keeping;
12861
12862        boolean success = true;
12863
12864        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12865
12866        if (app.curRawAdj != app.setRawAdj) {
12867            if (wasKeeping && !app.keeping) {
12868                // This app is no longer something we want to keep.  Note
12869                // its current wake lock time to later know to kill it if
12870                // it is not behaving well.
12871                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12872                synchronized (stats) {
12873                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12874                            app.pid, SystemClock.elapsedRealtime());
12875                }
12876                app.lastCpuTime = app.curCpuTime;
12877            }
12878
12879            app.setRawAdj = app.curRawAdj;
12880        }
12881
12882        if (app.curAdj != app.setAdj) {
12883            if (Process.setOomAdj(app.pid, app.curAdj)) {
12884                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12885                    TAG, "Set " + app.pid + " " + app.processName +
12886                    " adj " + app.curAdj + ": " + app.adjType);
12887                app.setAdj = app.curAdj;
12888            } else {
12889                success = false;
12890                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12891            }
12892        }
12893        if (app.setSchedGroup != app.curSchedGroup) {
12894            app.setSchedGroup = app.curSchedGroup;
12895            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12896                    "Setting process group of " + app.processName
12897                    + " to " + app.curSchedGroup);
12898            if (app.waitingToKill != null &&
12899                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12900                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12901                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12902                        app.processName, app.setAdj, app.waitingToKill);
12903                app.killedBackground = true;
12904                Process.killProcessQuiet(app.pid);
12905                success = false;
12906            } else {
12907                if (true) {
12908                    long oldId = Binder.clearCallingIdentity();
12909                    try {
12910                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12911                    } catch (Exception e) {
12912                        Slog.w(TAG, "Failed setting process group of " + app.pid
12913                                + " to " + app.curSchedGroup);
12914                        e.printStackTrace();
12915                    } finally {
12916                        Binder.restoreCallingIdentity(oldId);
12917                    }
12918                } else {
12919                    if (app.thread != null) {
12920                        try {
12921                            app.thread.setSchedulingGroup(app.curSchedGroup);
12922                        } catch (RemoteException e) {
12923                        }
12924                    }
12925                }
12926            }
12927        }
12928        return success;
12929    }
12930
12931    private final ActivityRecord resumedAppLocked() {
12932        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12933        if (resumedActivity == null || resumedActivity.app == null) {
12934            resumedActivity = mMainStack.mPausingActivity;
12935            if (resumedActivity == null || resumedActivity.app == null) {
12936                resumedActivity = mMainStack.topRunningActivityLocked(null);
12937            }
12938        }
12939        return resumedActivity;
12940    }
12941
12942    final boolean updateOomAdjLocked(ProcessRecord app) {
12943        final ActivityRecord TOP_ACT = resumedAppLocked();
12944        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12945        int curAdj = app.curAdj;
12946        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12947            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12948
12949        mAdjSeq++;
12950
12951        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12952                TOP_APP, false);
12953        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12954            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12955        if (nowHidden != wasHidden) {
12956            // Changed to/from hidden state, so apps after it in the LRU
12957            // list may also be changed.
12958            updateOomAdjLocked();
12959        }
12960        return success;
12961    }
12962
12963    final void updateOomAdjLocked() {
12964        final ActivityRecord TOP_ACT = resumedAppLocked();
12965        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12966
12967        if (false) {
12968            RuntimeException e = new RuntimeException();
12969            e.fillInStackTrace();
12970            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12971        }
12972
12973        mAdjSeq++;
12974        mNewNumServiceProcs = 0;
12975
12976        // Let's determine how many processes we have running vs.
12977        // how many slots we have for background processes; we may want
12978        // to put multiple processes in a slot of there are enough of
12979        // them.
12980        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
12981                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
12982        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
12983        if (emptyFactor < 1) emptyFactor = 1;
12984        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
12985        if (hiddenFactor < 1) hiddenFactor = 1;
12986        int stepHidden = 0;
12987        int stepEmpty = 0;
12988        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12989        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12990        int numHidden = 0;
12991        int numEmpty = 0;
12992        int numTrimming = 0;
12993
12994        mNumNonHiddenProcs = 0;
12995        mNumHiddenProcs = 0;
12996
12997        // First update the OOM adjustment for each of the
12998        // application processes based on their current state.
12999        int i = mLruProcesses.size();
13000        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13001        int nextHiddenAdj = curHiddenAdj+1;
13002        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13003        int nextEmptyAdj = curEmptyAdj+2;
13004        while (i > 0) {
13005            i--;
13006            ProcessRecord app = mLruProcesses.get(i);
13007            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13008            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13009            if (!app.killedBackground) {
13010                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13011                    // This process was assigned as a hidden process...  step the
13012                    // hidden level.
13013                    mNumHiddenProcs++;
13014                    if (curHiddenAdj != nextHiddenAdj) {
13015                        stepHidden++;
13016                        if (stepHidden >= hiddenFactor) {
13017                            stepHidden = 0;
13018                            curHiddenAdj = nextHiddenAdj;
13019                            nextHiddenAdj += 2;
13020                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13021                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13022                            }
13023                        }
13024                    }
13025                    numHidden++;
13026                    if (numHidden > hiddenProcessLimit) {
13027                        Slog.i(TAG, "No longer want " + app.processName
13028                                + " (pid " + app.pid + "): hidden #" + numHidden);
13029                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13030                                app.processName, app.setAdj, "too many background");
13031                        app.killedBackground = true;
13032                        Process.killProcessQuiet(app.pid);
13033                    }
13034                } else {
13035                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13036                        // This process was assigned as an empty process...  step the
13037                        // empty level.
13038                        if (curEmptyAdj != nextEmptyAdj) {
13039                            stepEmpty++;
13040                            if (stepEmpty >= emptyFactor) {
13041                                stepEmpty = 0;
13042                                curEmptyAdj = nextEmptyAdj;
13043                                nextEmptyAdj += 2;
13044                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13045                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13046                                }
13047                            }
13048                        }
13049                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13050                        mNumNonHiddenProcs++;
13051                    }
13052                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13053                        numEmpty++;
13054                        if (numEmpty > emptyProcessLimit) {
13055                            Slog.i(TAG, "No longer want " + app.processName
13056                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13057                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13058                                    app.processName, app.setAdj, "too many background");
13059                            app.killedBackground = true;
13060                            Process.killProcessQuiet(app.pid);
13061                        }
13062                    }
13063                }
13064                if (app.isolated && app.services.size() <= 0) {
13065                    // If this is an isolated process, and there are no
13066                    // services running in it, then the process is no longer
13067                    // needed.  We agressively kill these because we can by
13068                    // definition not re-use the same process again, and it is
13069                    // good to avoid having whatever code was running in them
13070                    // left sitting around after no longer needed.
13071                    Slog.i(TAG, "Isolated process " + app.processName
13072                            + " (pid " + app.pid + ") no longer needed");
13073                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13074                            app.processName, app.setAdj, "isolated not needed");
13075                    app.killedBackground = true;
13076                    Process.killProcessQuiet(app.pid);
13077                }
13078                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13079                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13080                        && !app.killedBackground) {
13081                    numTrimming++;
13082                }
13083            }
13084        }
13085
13086        mNumServiceProcs = mNewNumServiceProcs;
13087
13088        // Now determine the memory trimming level of background processes.
13089        // Unfortunately we need to start at the back of the list to do this
13090        // properly.  We only do this if the number of background apps we
13091        // are managing to keep around is less than half the maximum we desire;
13092        // if we are keeping a good number around, we'll let them use whatever
13093        // memory they want.
13094        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13095                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13096            final int numHiddenAndEmpty = numHidden + numEmpty;
13097            final int N = mLruProcesses.size();
13098            int factor = numTrimming/3;
13099            int minFactor = 2;
13100            if (mHomeProcess != null) minFactor++;
13101            if (mPreviousProcess != null) minFactor++;
13102            if (factor < minFactor) factor = minFactor;
13103            int step = 0;
13104            int fgTrimLevel;
13105            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13106                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13107            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13108                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13109            } else {
13110                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13111            }
13112            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13113            for (i=0; i<N; i++) {
13114                ProcessRecord app = mLruProcesses.get(i);
13115                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13116                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13117                        && !app.killedBackground) {
13118                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13119                        try {
13120                            app.thread.scheduleTrimMemory(curLevel);
13121                        } catch (RemoteException e) {
13122                        }
13123                        if (false) {
13124                            // For now we won't do this; our memory trimming seems
13125                            // to be good enough at this point that destroying
13126                            // activities causes more harm than good.
13127                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13128                                    && app != mHomeProcess && app != mPreviousProcess) {
13129                                // Need to do this on its own message because the stack may not
13130                                // be in a consistent state at this point.
13131                                // For these apps we will also finish their activities
13132                                // to help them free memory.
13133                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13134                            }
13135                        }
13136                    }
13137                    app.trimMemoryLevel = curLevel;
13138                    step++;
13139                    if (step >= factor) {
13140                        step = 0;
13141                        switch (curLevel) {
13142                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13143                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13144                                break;
13145                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13146                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13147                                break;
13148                        }
13149                    }
13150                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13151                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13152                            && app.thread != null) {
13153                        try {
13154                            app.thread.scheduleTrimMemory(
13155                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13156                        } catch (RemoteException e) {
13157                        }
13158                    }
13159                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13160                } else {
13161                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13162                            && app.pendingUiClean) {
13163                        // If this application is now in the background and it
13164                        // had done UI, then give it the special trim level to
13165                        // have it free UI resources.
13166                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13167                        if (app.trimMemoryLevel < level && app.thread != null) {
13168                            try {
13169                                app.thread.scheduleTrimMemory(level);
13170                            } catch (RemoteException e) {
13171                            }
13172                        }
13173                        app.pendingUiClean = false;
13174                    }
13175                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13176                        try {
13177                            app.thread.scheduleTrimMemory(fgTrimLevel);
13178                        } catch (RemoteException e) {
13179                        }
13180                    }
13181                    app.trimMemoryLevel = fgTrimLevel;
13182                }
13183            }
13184        } else {
13185            final int N = mLruProcesses.size();
13186            for (i=0; i<N; i++) {
13187                ProcessRecord app = mLruProcesses.get(i);
13188                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13189                        && app.pendingUiClean) {
13190                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13191                            && app.thread != null) {
13192                        try {
13193                            app.thread.scheduleTrimMemory(
13194                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13195                        } catch (RemoteException e) {
13196                        }
13197                    }
13198                    app.pendingUiClean = false;
13199                }
13200                app.trimMemoryLevel = 0;
13201            }
13202        }
13203
13204        if (mAlwaysFinishActivities) {
13205            // Need to do this on its own message because the stack may not
13206            // be in a consistent state at this point.
13207            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13208        }
13209    }
13210
13211    final void trimApplications() {
13212        synchronized (this) {
13213            int i;
13214
13215            // First remove any unused application processes whose package
13216            // has been removed.
13217            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13218                final ProcessRecord app = mRemovedProcesses.get(i);
13219                if (app.activities.size() == 0
13220                        && app.curReceiver == null && app.services.size() == 0) {
13221                    Slog.i(
13222                        TAG, "Exiting empty application process "
13223                        + app.processName + " ("
13224                        + (app.thread != null ? app.thread.asBinder() : null)
13225                        + ")\n");
13226                    if (app.pid > 0 && app.pid != MY_PID) {
13227                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13228                                app.processName, app.setAdj, "empty");
13229                        Process.killProcessQuiet(app.pid);
13230                    } else {
13231                        try {
13232                            app.thread.scheduleExit();
13233                        } catch (Exception e) {
13234                            // Ignore exceptions.
13235                        }
13236                    }
13237                    cleanUpApplicationRecordLocked(app, false, true, -1);
13238                    mRemovedProcesses.remove(i);
13239
13240                    if (app.persistent) {
13241                        if (app.persistent) {
13242                            addAppLocked(app.info, false);
13243                        }
13244                    }
13245                }
13246            }
13247
13248            // Now update the oom adj for all processes.
13249            updateOomAdjLocked();
13250        }
13251    }
13252
13253    /** This method sends the specified signal to each of the persistent apps */
13254    public void signalPersistentProcesses(int sig) throws RemoteException {
13255        if (sig != Process.SIGNAL_USR1) {
13256            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13257        }
13258
13259        synchronized (this) {
13260            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13261                    != PackageManager.PERMISSION_GRANTED) {
13262                throw new SecurityException("Requires permission "
13263                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13264            }
13265
13266            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13267                ProcessRecord r = mLruProcesses.get(i);
13268                if (r.thread != null && r.persistent) {
13269                    Process.sendSignal(r.pid, sig);
13270                }
13271            }
13272        }
13273    }
13274
13275    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13276        if (proc == null || proc == mProfileProc) {
13277            proc = mProfileProc;
13278            path = mProfileFile;
13279            profileType = mProfileType;
13280            clearProfilerLocked();
13281        }
13282        if (proc == null) {
13283            return;
13284        }
13285        try {
13286            proc.thread.profilerControl(false, path, null, profileType);
13287        } catch (RemoteException e) {
13288            throw new IllegalStateException("Process disappeared");
13289        }
13290    }
13291
13292    private void clearProfilerLocked() {
13293        if (mProfileFd != null) {
13294            try {
13295                mProfileFd.close();
13296            } catch (IOException e) {
13297            }
13298        }
13299        mProfileApp = null;
13300        mProfileProc = null;
13301        mProfileFile = null;
13302        mProfileType = 0;
13303        mAutoStopProfiler = false;
13304    }
13305
13306    public boolean profileControl(String process, boolean start,
13307            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13308
13309        try {
13310            synchronized (this) {
13311                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13312                // its own permission.
13313                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13314                        != PackageManager.PERMISSION_GRANTED) {
13315                    throw new SecurityException("Requires permission "
13316                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13317                }
13318
13319                if (start && fd == null) {
13320                    throw new IllegalArgumentException("null fd");
13321                }
13322
13323                ProcessRecord proc = null;
13324                if (process != null) {
13325                    try {
13326                        int pid = Integer.parseInt(process);
13327                        synchronized (mPidsSelfLocked) {
13328                            proc = mPidsSelfLocked.get(pid);
13329                        }
13330                    } catch (NumberFormatException e) {
13331                    }
13332
13333                    if (proc == null) {
13334                        HashMap<String, SparseArray<ProcessRecord>> all
13335                                = mProcessNames.getMap();
13336                        SparseArray<ProcessRecord> procs = all.get(process);
13337                        if (procs != null && procs.size() > 0) {
13338                            proc = procs.valueAt(0);
13339                        }
13340                    }
13341                }
13342
13343                if (start && (proc == null || proc.thread == null)) {
13344                    throw new IllegalArgumentException("Unknown process: " + process);
13345                }
13346
13347                if (start) {
13348                    stopProfilerLocked(null, null, 0);
13349                    setProfileApp(proc.info, proc.processName, path, fd, false);
13350                    mProfileProc = proc;
13351                    mProfileType = profileType;
13352                    try {
13353                        fd = fd.dup();
13354                    } catch (IOException e) {
13355                        fd = null;
13356                    }
13357                    proc.thread.profilerControl(start, path, fd, profileType);
13358                    fd = null;
13359                    mProfileFd = null;
13360                } else {
13361                    stopProfilerLocked(proc, path, profileType);
13362                    if (fd != null) {
13363                        try {
13364                            fd.close();
13365                        } catch (IOException e) {
13366                        }
13367                    }
13368                }
13369
13370                return true;
13371            }
13372        } catch (RemoteException e) {
13373            throw new IllegalStateException("Process disappeared");
13374        } finally {
13375            if (fd != null) {
13376                try {
13377                    fd.close();
13378                } catch (IOException e) {
13379                }
13380            }
13381        }
13382    }
13383
13384    public boolean dumpHeap(String process, boolean managed,
13385            String path, ParcelFileDescriptor fd) throws RemoteException {
13386
13387        try {
13388            synchronized (this) {
13389                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13390                // its own permission (same as profileControl).
13391                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13392                        != PackageManager.PERMISSION_GRANTED) {
13393                    throw new SecurityException("Requires permission "
13394                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13395                }
13396
13397                if (fd == null) {
13398                    throw new IllegalArgumentException("null fd");
13399                }
13400
13401                ProcessRecord proc = null;
13402                try {
13403                    int pid = Integer.parseInt(process);
13404                    synchronized (mPidsSelfLocked) {
13405                        proc = mPidsSelfLocked.get(pid);
13406                    }
13407                } catch (NumberFormatException e) {
13408                }
13409
13410                if (proc == null) {
13411                    HashMap<String, SparseArray<ProcessRecord>> all
13412                            = mProcessNames.getMap();
13413                    SparseArray<ProcessRecord> procs = all.get(process);
13414                    if (procs != null && procs.size() > 0) {
13415                        proc = procs.valueAt(0);
13416                    }
13417                }
13418
13419                if (proc == null || proc.thread == null) {
13420                    throw new IllegalArgumentException("Unknown process: " + process);
13421                }
13422
13423                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13424                if (!isDebuggable) {
13425                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13426                        throw new SecurityException("Process not debuggable: " + proc);
13427                    }
13428                }
13429
13430                proc.thread.dumpHeap(managed, path, fd);
13431                fd = null;
13432                return true;
13433            }
13434        } catch (RemoteException e) {
13435            throw new IllegalStateException("Process disappeared");
13436        } finally {
13437            if (fd != null) {
13438                try {
13439                    fd.close();
13440                } catch (IOException e) {
13441                }
13442            }
13443        }
13444    }
13445
13446    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13447    public void monitor() {
13448        synchronized (this) { }
13449    }
13450
13451    void onCoreSettingsChange(Bundle settings) {
13452        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13453            ProcessRecord processRecord = mLruProcesses.get(i);
13454            try {
13455                if (processRecord.thread != null) {
13456                    processRecord.thread.setCoreSettings(settings);
13457                }
13458            } catch (RemoteException re) {
13459                /* ignore */
13460            }
13461        }
13462    }
13463
13464    // Multi-user methods
13465
13466    public boolean switchUser(int userId) {
13467        final int callingUid = Binder.getCallingUid();
13468        if (callingUid != 0 && callingUid != Process.myUid()) {
13469            Slog.e(TAG, "Trying to switch user from unauthorized app");
13470            return false;
13471        }
13472        if (mCurrentUserId == userId)
13473            return true;
13474
13475        synchronized (this) {
13476            // Check if user is already logged in, otherwise check if user exists first before
13477            // adding to the list of logged in users.
13478            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13479                if (!userExists(userId)) {
13480                    return false;
13481                }
13482                mLoggedInUsers.append(userId, userId);
13483            }
13484
13485            mCurrentUserId = userId;
13486            boolean haveActivities = mMainStack.switchUser(userId);
13487            if (!haveActivities) {
13488                startHomeActivityLocked(userId);
13489            }
13490
13491        }
13492
13493        // Inform of user switch
13494        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13495        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13496        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13497
13498        return true;
13499    }
13500
13501    @Override
13502    public UserInfo getCurrentUser() throws RemoteException {
13503        final int callingUid = Binder.getCallingUid();
13504        if (callingUid != 0 && callingUid != Process.myUid()) {
13505            Slog.e(TAG, "Trying to get user from unauthorized app");
13506            return null;
13507        }
13508        return getUserManager().getUserInfo(mCurrentUserId);
13509    }
13510
13511    private void onUserRemoved(Intent intent) {
13512        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13513        if (extraUserId < 1) return;
13514
13515        // Kill all the processes for the user
13516        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13517        synchronized (this) {
13518            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13519            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13520                SparseArray<ProcessRecord> uids = uidMap.getValue();
13521                for (int i = 0; i < uids.size(); i++) {
13522                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13523                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13524                    }
13525                }
13526            }
13527
13528            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13529                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13530                        false, false, true, true, extraUserId);
13531            }
13532        }
13533    }
13534
13535    private boolean userExists(int userId) {
13536        UserInfo user = getUserManager().getUserInfo(userId);
13537        return user != null;
13538    }
13539
13540    UserManager getUserManager() {
13541        if (mUserManager == null) {
13542            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13543        }
13544        return mUserManager;
13545    }
13546
13547    private void checkValidCaller(int uid, int userId) {
13548        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13549
13550        throw new SecurityException("Caller uid=" + uid
13551                + " is not privileged to communicate with user=" + userId);
13552    }
13553
13554    private int applyUserId(int uid, int userId) {
13555        return UserHandle.getUid(userId, uid);
13556    }
13557
13558    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13559        if (info == null) return null;
13560        ApplicationInfo newInfo = new ApplicationInfo(info);
13561        newInfo.uid = applyUserId(info.uid, userId);
13562        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13563                + info.packageName;
13564        return newInfo;
13565    }
13566
13567    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13568        if (aInfo == null
13569                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13570            return aInfo;
13571        }
13572
13573        ActivityInfo info = new ActivityInfo(aInfo);
13574        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13575        return info;
13576    }
13577}
13578